Bash开始使用Bash


版本

发布日期
0.99 1989年6月8日
1.01 1989年6月23日
2.0 1996-12-31
2.02 1998年4月20日
2.03 1999年2月19日
2.04 2001-03-21
2.05b以上 2002-07-17
3.0 2004-08-03
3.1 2005-12-08
3.2 2006-10-11
4 2009-02-20
4.1 2009-12-31
4.2 2011-02-13
4.3 2014年2月26日
4.4 2016年9月15日

处理命名参数

#!/bin/bash

deploy=false
uglify=false

while (( $# > 1 )); do case $1 in
   --deploy) deploy="$2";;
   --uglify) uglify="$2";;
   *) break;
 esac; shift 2
done

$deploy && echo "will deploy... deploy = $deploy"
$uglify && echo "will uglify... uglify = $uglify"

# how to run
# chmod +x script.sh
# ./script.sh --deploy true --uglify false
 

你好,世界

互动壳牌

Bash shell通常以交互方式使用它允许您输入和编辑命令,然后在按Return键时执行它们。许多基于Unix和类Unix操作系统使用Bash作为其默认shell(特别是Linux和macOS)。终端在启动时自动进入交互式Bash shell进程。

键入以下内容输出Hello World

echo "Hello World"
#> Hello World  # Output Example
 

笔记

  • 您只需在终端中键入shell的名称即可更改shell。例如: shbash

  • echo 是一个Bash内置命令,它将接收的参数写入标准输出。默认情况下,它会在输出中附加换行符。


非交互式外壳

Bash shell也可以从脚本非交互式运行,使shell不需要人工交互。交互行为和脚本行为应该是相同的 - 这是Unix V7 Bourne shell和传递Bash的重要设计考虑因素。因此,可以在命令行中执行的任何操作都可以放在脚本文件中以供重用。

请按照以下步骤创建Hello World 脚本:

  1. 创建一个名为hello-world.sh 的新文件

    touch hello-world.sh
     
  2. 通过运行chmod +x hello-world.sh 使脚本可执行

  3. 添加此代码:

    #!/bin/bash
    echo "Hello World"
     

    第1行:脚本的第一行必须以字符序列#! 开头#! ,简称shebang 1 。 shebang指示操作系统运行/bin/bash ,即Bash shell,将脚本的路径作为参数传递给它。

    例如/bin/bash hello-world.sh

    第2行 :使用echo 命令将Hello World 写入标准输出。

  1. 使用以下命令之一从命令行执行hello-world.sh 脚本:

    • ./hello-world.sh - 最常用,推荐
    • /bin/bash hello-world.sh
    • bash hello-world.sh - 假设/bin$PATH
    • sh hello-world.sh

对于实际的生产用途,你会省略.sh 扩展名(无论如何都会误导,因为这是一个Bash脚本,而不是sh 脚本),并且可能会将文件移动到PATH 的目录中,以便无论是否可以使用它。您当前的工作目录,就像系统命令,如catls

常见错误包括:

  1. 忘记对文件应用执行权限,即chmod +x hello-world.sh ,导致chmod +x hello-world.sh 的输出./hello-world.sh: Permission denied

  2. 在Windows上编辑脚本,这会产生Bash无法处理的错误行结束字符。

    常见的症状是: command not found 在回车将光标强制到行首的位置: command not found ,覆盖错误消息中冒号前的文本。

    可以使用dos2unix 程序修复脚本。

    使用示例: dos2unix hello-world.sh

    dos2unix 内联编辑文件。

  3. 使用sh ./hello-world.sh ,没有意识到bashsh 是具有不同特征的不同shell(尽管由于Bash是向后兼容的,因此相反的错误是无害的)。

    无论如何,仅仅依靠脚本的shebang行比在每个脚本的文件名之前显式写bashsh (或pythonperlawkruby 或...)更为可取。

    为了使脚本更具可移植性而使用的常见shebang行是使用#!/usr/bin/env bash 而不是硬编码Bash的路径。这样, /usr/bin/env 必须存在,但除此之外, bash 只需要在你的PATH 。在许多系统上, /bin/bash 不存在,你应该使用/usr/local/bin/bash 或其他一些绝对路径;这种变化避免了弄清楚细节。


1 也称为sha-bang,hashbang,pound-bang,hash-pling。

“调试”模式下的Hello World

$ cat hello.sh 
#!/bin/bash 
echo "Hello World"
$ bash -x hello.sh 
+ echo Hello World
Hello World
 

-x 参数使您可以遍历脚本中的每一行。这里有一个很好的例子:

$ cat hello.sh
#!/bin/bash 
echo "Hello World\n" 
adding_string_to_number="s"
v=$(expr 5 + $adding_string_to_number) 

$ ./hello.sh 
Hello World

expr: non-integer argument
 

以上提示错误不足以跟踪脚本;但是,使用以下方法可以更好地了解在脚本中查找错误的位置。

$ bash -x hello.sh 
+ echo Hello World\n
Hello World

+ adding_string_to_number=s
+ expr 5 + s
expr: non-integer argument
+ v=
 

Hello World使用变量

使用以下内容创建一个名为hello.sh 的新文件,并使用chmod +x hello.sh 为其授予可执行权限。

执行/运行: ./hello.sh

#!/usr/bin/env bash

# Note that spaces cannot be used around the `=` assignment operator
whom_variable="World"

# Use printf to safely output the data
printf "Hello, %s\n" "$whom_variable"
#> Hello, World
 

这将在执行时将Hello, World 打印到标准输出。

要告诉bash你需要非常具体的脚本,通过将其指向包含目录,通常使用./ 如果它是你的工作目录,在哪里. 是当前目录的别名。如果未指定目录, bash 尝试在$PATH 环境变量中包含的某个目录中找到该脚本。


下面的代码接受一个参数$1 ,这是第一个命令行参数,并在一个格式化的字符串中输出它,在Hello,

执行/运行: ./hello.sh World

#!/usr/bin/env bash
printf "Hello, %s\n" "$1"
#> Hello, World
 

值得注意的是, $1 必须以双引号引用,而不是单引号。 "$1" 根据需要扩展到第一个命令行参数,而'$1' 计算为文字字符串$1

安全说明:
阅读忘记在bash shell中引用变量的安全含义,以了解将变量文本放在双引号内的重要性。

用户输入的Hello World

以下将提示用户输入,然后将该输入作为字符串(文本)存储在变量中。然后使用该变量向用户发送消息。

#!/usr/bin/env bash
echo  "Who are you?"
read name
echo "Hello, $name."
 

命令read 这里从标准输入读取数据的一行入变量name 。然后使用$name 引用它,并使用echo 打印到标准输出。

输出示例:

$ ./hello_world.sh
Who are you?
Matt
Hello, Matt.
 

在这里,用户输入了名称“Matt”,此代码用于表示Hello, Matt.

如果要在打印时将某些内容附加到变量值,请在变量名称周围使用大括号,如下例所示:

#!/usr/bin/env bash
echo  "What are you doing?"
read action
echo "You are ${action}ing."
 

输出示例:

$ ./hello_world.sh
What are you doing?
Sleep
You are Sleeping.
 

在此处,当用户输入动作时,在打印时将“ing”附加到该动作。

在字符串中引用的重要性

引用对于bash中的字符串扩展很重要。通过这些,您可以控制bash如何解析和扩展字符串。

引用有两种类型:

  • 使用双引号:“
  • 使用单引号:'

如果你想bash扩展你的论点,你可以使用弱报价

#!/usr/bin/env bash
world="World"
echo "Hello $world"
#> Hello World
 

如果您不想bash扩展您的参数,可以使用强引号

#!/usr/bin/env bash
world="World"
echo 'Hello $world'
#> Hello $world
 

您还可以使用escape来防止扩展:

#!/usr/bin/env bash
world="World"
echo "Hello \$world"
#> Hello $world
 

有关初学者详细信息以外的更多详细信息,您可以在此处继续阅读。

查看Bash内置函数的信息

help <command>
 

这将显示指定内置的Bash帮助(手动)页面。

例如, help unset 将显示:

unset: unset [-f] [-v] [-n] [name ...]
   Unset values and attributes of shell variables and functions.

   For each NAME, remove the corresponding variable or function.

   Options:
     -f    treat each NAME as a shell function
     -v    treat each NAME as a shell variable
     -n    treat each NAME as a name reference and unset the variable itself
       rather than the variable it references

   Without options, unset first tries to unset a variable, and if that fails,
   tries to unset a function.

   Some variables cannot be unset; also see `readonly'.

   Exit Status:
   Returns success unless an invalid option is given or a NAME is read-only.
 

要查看包含简短描述的所有内置列表,请使用

help -d