本文共 5156 字,大约阅读时间需要 17 分钟。
shell脚本通常以#!/bin/bash
起始
脚本的执行方式有两种。
将脚本名作为命令行参数: bash myScript.sh
授予脚本执行权限,将其变为可执行文件: chmod 755 myScript.sh ./myScript.sh
$ echo "Welcome to Bash" Welcome to Bash
双引号允许shell解释字符串中出现的特殊字符。单引号不会对其做任何解释
echo -e
接受双包含转义序列的双引号字符串作为参数
echo -e "1\t2\t3" 1 2 3
文本颜色是由对应的色彩码来描述的。其中包括:重置=0,黑色=30,红色=31,绿色=32, 黄色=33,蓝色=34,洋红=35,青色=36,白色=37
echo -e "\e[1;31m This is red text \e[0m"
彩色背景,经常使用的颜色码是:重置=0,黑色=40,红色=41,绿色=42,黄色=43, 蓝色=44,洋红=45,青色=46,白色=47
echo -e "\e[1;42m Green Background \e[0m"
var="value" # 将"value"赋给变量var echo $var
用env
或printenv
命令查看当前shell 中所定义的全部环境变量
在PATH中添加一条新路径,可以使用如下命令:
export PATH="$PATH:/home/user/bin"
另外还有一些众所周知的环境变量:HOME
、PWD
、USER
、UID
、SHELL
等
获得字符串的长度
$ var=12345678901234567890 $ echo ${ #var} 20
识别当前所使用的shell echo $SHELL
、 echo $0
If [ $UID -ne 0 ]; then echo Non root user. Please run as root. else echo Root user fi
操作符[]
result=$[ no1 + no2 ]
在[]
中可以使用$
前缀
result=$[ $no1 + 5 ]
文件描述符是与某个打开的文件或数据流相关联的整数。文件描述符0、 1以及2是系统预留的
使用大于号将文本保存到文件中 $ echo "This is a sample text 1" > temp.txt
$ echo "This is sample text 2" >> temp.txt
使用2>(数字2以及大于号)将stderr重定向到out.txt $ ls + 2> out.txt
有一种方法既可以将数据重定向到文件,还可以提供一份重定向数据的副本作为管道中后续命令的stdin。tee
命令从stdin中读取,然后将输入数据重定向到stdout以及一个或多个文件中
command | tee FILE1 FILE2 | otherCommand $ cat a* | tee out.txt | cat -n
重定向脚本内部的文本块
#!/bin/bash cat<log.txt This is a generated file. Do not edit. Changes will be overwritten. EOF
出现在cat <<EOF>log.txt
与下一个EOF行之间的所有文本行都会被当作stdin数据。 log.txt文件的内容显示如下:
$ cat log.txt This is a generated file. Do not edit. Changes will be overwritten.
在单行中使用数值列表来定义一个数组
array_var=(test1 test2 test3 test4 test5 test6) #这些值将会存储在以0为起始索引的连续位置上
打印出特定索引的数组元素内容
echo ${ array_var[0]} test1 index=5 echo ${ array_var[$index]} test6
以列表形式打印出数组中的所有值
$ echo ${ array_var[*]} test1 test2 test3 test4 test5 test6
打印数组长度(即数组中元素的个数):
$ echo ${ #array_var[*]}6
关联数组中,我们可以用任意的文本作为数组索引。首先,需要使用声明语句将一个变量 定义为关联数组:
$ declare -A fruits_value $ fruits_value=([apple]='100 dollars' [orange]='150 dollars')
显示数组内容:
$ echo "Apple costs ${fruits_value[apple]}" Apple costs 100 dollars
列出数组索引
$ echo ${ !fruits_value[*]} orange apple
创建别名
$ alias new_command='command sequence'
下面的命令为apt-get install
创建了一个别名:
$ alias install='sudo apt-get install'
alias命令的效果只是暂时的。一旦关闭当前终端,所有设置过的别名就失效了。为了 使别名在所有的shell中都可用,可以将其定义放入~/.bashrc
文件中
$ echo 'alias cmd="command seq"' >> ~/.bashrc
如果需要删除别名,只需将其对应的定义(如果有的话)从~/.bashrc
中删除,或者使用 unalias
命令。也可以使用alias example=
,这会取消别名example
tput
命令的功能演示
tput cols tput lines
打印出当前的终端名:
tput longname
将光标移动到坐标(100,100)处:
tput cup 100 100
设置终端背景色:
tput setb n #其中,n可以在0到7之间取值。
设置终端前景色:
tput setf n# 其中,n可以在0到7之间取值。
设置文本样式为粗体:
tput bold
设置下划线的起止:
tput smul tput rmul
删除从当前光标位置到行尾的所有内容:
tput ed
输入密码时,脚本不应该显示输入内容。在下面的例子中,我们将看到如何使用stty
来 实现这一需求
#!/bin/sh #Filename: password.sh echo -e "Enter password: " # 在读取密码前禁止回显 stty -echo read password # 重新允许回显 stty echo echo echo Password read.
stty
命令的选项-echo
禁止将输出发送到终端,而选项echo
则允许发送输出。
使用选项-x
,启用shell脚本的跟踪调试功能:
$ bash -x script.sh
使用set -x
和set +x
对脚本进行部分调试
#!/bin/bash #文件名: debug.sh for i in { 1..6}; do set -x echo $i set +x done echo "Script executed"
在上面的脚本中,只会打印出echo $i
的调试信息,因为使用-x和+x对调试区域进行 了限制。
set -x
:在执行时显示参数和命令。
set +x
:禁止调试。 set -v
:当命令进行读取时显示输入。 set +v
:禁止打印输入。 把第一行从#!/bin/bash
改成 #!/bin/bash -xv
,这样一来,不用任何其他选项就可以 启用调试功能了
$0
是脚本名称。$1
是第一个参数。$2
是第二个参数。$n
是第n个参数。$@
“被扩展成”$1” “$2” "$3"等。$*
“被扩展成”$1c$2c$3”,其中c是IFS的第一个字符。$@
“要比”$*
“用得多。由于”$*
"将所有的参数当作单个字符串,因此它很少被使用。函数和别名乍一看很相似,不过两者在行为上还是略有不同。大的差异在于函数参数可以 在函数体中任意位置上使用,而别名只能将参数放在命令尾部。
如果想获得/sbin/ifconfig
文件中设备对应的IP地址,可以尝试这样做:
$> alias wontWork='/sbin/ifconfig | grep' $> wontWork eth0 eth0 Link encap:Ethernet HWaddr 00:11::22::33::44:55
如果我们使用函数来实现的话,可以将 设备名作为参数传入ifconfig
,不再交给grep
:
$> function getIP() { /sbin/ifconfig $1 | grep 'inet '; } $> getIP eth0 inet addr:192.168.1.2 Bcast:192.168.255.255 Mask:255.255.0.0
shift
命令可以将参数依次向左移动一个位 置,让脚本能够使用$1
来访问到每一个参数
$ cat showArgs.sh for i in `seq 1 $#` do echo $i is $1 shift done $ sh showArgs.sh a b c 1 is a 2 is b 3 is c
从输入中读取n个字符并存入变量variable_name:
read -n number_of_chars variable_name
用无回显的方式读取密码:
read -s var
使用read显示提示信息:
read -p "Enter input:" var
在给定时限内读取输入:
read -t timeout var
例如:
$ read -t 2 var #在2秒内将键入的字符串读入变量var
用特定的定界符作为输入行的结束:
read -d delim_char var
例如:
$ read -d ":" var hello: #var被设置为hello
们可以用if、 if else以及逻辑运算符来测试
[ condition ] && action;
# 如果condition为真,则执行action
[ condition ] || action;
# 如果condition为假,则执行action 算术比较
[$var
-eq 0 ] #当$var
等于0时,返回真 [ $var
-ne 0 ] #当$var
不为0时,返回真 ● -gt:大于。 ● -lt:小于。 ● -ge:大于或等于。 ● -le:小于或等于 -a是逻辑与操作符,-o是逻辑或操作符 文件系统相关测试
● [ -f $file_var ]:如果给定的变量包含正常的文件路径或文件名,则返回真。 ● [ -x $var ]:如果给定的变量包含的文件可执行,则返回真。 ● [ -d $var ]:如果给定的变量包含的是目录,则返回真。 ● [ -e $var ]:如果给定的变量包含的文件存在,则返回真。 ● [ -c $var ]:如果给定的变量包含的是一个字符设备文件的路径,则返回真。 ● [ -b $var ]:如果给定的变量包含的是一个块设备文件的路径,则返回真。 ● [ -w $var ]:如果给定的变量包含的文件可写,则返回真。 ● [ -r $var ]:如果给定的变量包含的文件可读,则返回真。 ● [ -L $var ]:如果给定的变量包含的是一个符号链接,则返回真。字符串比较
● [[ -z $str1 ]]:如果str1为空串,则返回真。 ● [[ -n $str1 ]]:如果str1不为空串,则返回真。转载地址:http://wyhpi.baihongyu.com/