Linux Bash编程需要注意的几个地方
2015-05-19 00:00
330 查看
摘要: bash脚本编程需要注意的几个小问题.
日常开发基本都在linux环境下,bash命令用的不少,但是写脚本的地方不多。真的写起来,发现需要注意的语法、使用习惯的小问题还是不少。
查了些资料,也结合自己工作中遇到的一些问题,列举几个需要注意的地方
1. 变量及赋值
用等号给变量赋值,=前后都不能有空格。
export可以将其设为环境变量,当前SHELL及子进程有效;父进程的自定义变量无法在子进程中使用。
declare -x var也可讲变量设为环境变量。变量赋值,默认是string类型,通过declare命令可改成其他类型,比如:
2. 重定向
重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。
> 写入文件并覆盖旧文件
>> 加到文件的尾部,保留旧文件内容。
3. 单引号/双引号/反引号
单引号 '
两个单引号包围起来的字符串就是普通的字符串,它将保留原始的字面意思。
双引号"
两个双引号包围起来的字符串,部分特殊字符将起到它们的作用.
这些特殊字符有: 美元符$, 反斜杠\, 反引号', 感叹号!.
反引号 `
两个反引号包围起来的字符串,将作为命令来运行,
执行的输出结果作为该反引号的内容,称为命令替换,
它有另一种更好的写法: $(command)
4. if 控制语句
if [ ... ] then
...
elif ... then
...
else
...
fi
用" [ ] "来表示条件测试。注意这里的空格很重要!要确保方括号的空格。
[ -f "somefile" ] :判断是否是一个文件
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
[ -n "$var" ] :判断$var变量是否有值
[ "$a" == "$b" ] :判断$a和$b是否相等
5. 循环控制
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
6. 使用{}增强变量的功能
? : 变量未定义,则显示提示语word,脚本执行结束;
- : 变量未定义, 则使用新值word; 不改变变量原来的状态;
+: 变量定义, 则使用新值word; 不改变变量原来的状态; 与?不同的是,脚本不会停止执行;
=: 变量未定义, 则使用新值word, 并定义到变量;
变量有未定义与空值之分,要同时对这两种情况都进行判断,可以在上面的方法中加入冒号: 增加功能:
例如:
7. Bash中的特殊变量:位置变量等
位置变量:$1~$9, 代表传入给执行脚本的参数,从1开始,最多可以有9个。例如,下面的脚本根据输入的名字实现重命名功能:
如果传入的参数超过9个,或者说想传入任意数量的参数,可以用shift命令,来移除传入的参数,例如:
$0 - 脚本名字
$* - 所有的位置参数
使用这个变量,同样可以操作超过10个的位置参数。例如下面这个脚本,可以把任意多个的文件移动到一个文件夹下:
$@ - 所有的位置参数(参数可包含空格)
此变量与$*的基本功能类似,不同的地方是,@可以处理包含空格的参数。空格可以分隔输入参数,如果输入参数包含空格,$@可以返回包含空格的参数,$*则不能。可以参考下面的例子来理解:
首先有一个打印变量名的脚本EchoArgs
再写一个测试脚本TestEchoArgs.sh
测试输入结果,比较两个命令的不同:
分析:
$# - 参数个数
shift $#可以去掉所有的传入参数。
$$ - 当前进程的ID
由于进程的ID都是不同的,这个变量可以用来命名唯一的临时文件。例如下面这个脚本,返回行数:
另一个用处是,可以在其他进程中通过$$来kill这个进程。例如:
$! - 后台进程的PID
只有运行&命令的进程才会改变$!.使用此命令可以控制多个后台运行的程序,比如:
$? - 错误状态
返回前一个程序的退出状态。
----------
未完,不定时更新...
Last updated - 2/23/2016
日常开发基本都在linux环境下,bash命令用的不少,但是写脚本的地方不多。真的写起来,发现需要注意的语法、使用习惯的小问题还是不少。
查了些资料,也结合自己工作中遇到的一些问题,列举几个需要注意的地方
1. 变量及赋值
用等号给变量赋值,=前后都不能有空格。
export可以将其设为环境变量,当前SHELL及子进程有效;父进程的自定义变量无法在子进程中使用。
var=32 now=`date +%y%m%d%H` cur_path=`dirname $0` PATH=$PATH:/home/user/bin
declare -x var也可讲变量设为环境变量。变量赋值,默认是string类型,通过declare命令可改成其他类型,比如:
declare -i sum=12+34 #i = integer declare -a ... #a = array
2. 重定向
重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。
> 写入文件并覆盖旧文件
>> 加到文件的尾部,保留旧文件内容。
3. 单引号/双引号/反引号
单引号 '
两个单引号包围起来的字符串就是普通的字符串,它将保留原始的字面意思。
双引号"
两个双引号包围起来的字符串,部分特殊字符将起到它们的作用.
这些特殊字符有: 美元符$, 反斜杠\, 反引号', 感叹号!.
反引号 `
两个反引号包围起来的字符串,将作为命令来运行,
执行的输出结果作为该反引号的内容,称为命令替换,
它有另一种更好的写法: $(command)
tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`
4. if 控制语句
if [ ... ] then
...
elif ... then
...
else
...
fi
用" [ ] "来表示条件测试。注意这里的空格很重要!要确保方括号的空格。
[ -f "somefile" ] :判断是否是一个文件
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
[ -n "$var" ] :判断$var变量是否有值
[ "$a" == "$b" ] :判断$a和$b是否相等
5. 循环控制
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
6. 使用{}增强变量的功能
? : 变量未定义,则显示提示语word,脚本执行结束;
- : 变量未定义, 则使用新值word; 不改变变量原来的状态;
+: 变量定义, 则使用新值word; 不改变变量原来的状态; 与?不同的是,脚本不会停止执行;
=: 变量未定义, 则使用新值word, 并定义到变量;
变量有未定义与空值之分,要同时对这两种情况都进行判断,可以在上面的方法中加入冒号: 增加功能:
例如:
$ # a is undefined $ b="" $ c="Z" $ echo a=${a-1}, b=${b-2}, c=${c-3} a=1, b=, c=Z $ echo a=${a:-1}, b=${b:-2}, c=${c:-3} a=1, b=2, c=Z
7. Bash中的特殊变量:位置变量等
位置变量:$1~$9, 代表传入给执行脚本的参数,从1开始,最多可以有9个。例如,下面的脚本根据输入的名字实现重命名功能:
#!/bin/sh # rename: - rename a file # Usage: rename oldname newname oldname=$1 newname=$2 mv ${oldname:?"missing"} ${newname:?"missing"}
如果传入的参数超过9个,或者说想传入任意数量的参数,可以用shift命令,来移除传入的参数,例如:
#!/bin/sh arg1=$1;shift; arg2=$1;shift; arg3=$1;shift; echo first three arguments are $arg1 $arg2 and $arg3
#!/bin/sh arg1=$1 arg2=$2 arg3=$3;shift 3 echo first three arguments are $arg1 $arg2 and $arg3
$0 - 脚本名字
$* - 所有的位置参数
使用这个变量,同样可以操作超过10个的位置参数。例如下面这个脚本,可以把任意多个的文件移动到一个文件夹下:
#!/bin/sh # scriptname: moveto # usage: # moveto directory files..... directory=${1:?"Missing"};shift mv $* $directory 调用的方法: ./moveto.sh /mytmp *.txt
$@ - 所有的位置参数(参数可包含空格)
此变量与$*的基本功能类似,不同的地方是,@可以处理包含空格的参数。空格可以分隔输入参数,如果输入参数包含空格,$@可以返回包含空格的参数,$*则不能。可以参考下面的例子来理解:
首先有一个打印变量名的脚本EchoArgs
#!/bin/sh # ================ # usage: # echoes arguments # ================ E="echo -n" # echo the name of script ${E} $0: # now echo each argument ${E} "'${1-"?"}'" ${E} "'${2-"?"}'" ${E} "'${3-"?"}'" ${E} "'${4-"?"}'" ${E} "'${5-"?"}'" ${E} "'${6-"?"}'" ${E} "'${7-"?"}'" echo
再写一个测试脚本TestEchoArgs.sh
#!/bin/sh # ================ # usage: # test echoes arguments # ================ ./EchoArgs $* ./EchoArgs $@ ./EchoArgs "$*" ./EchoArgs "$@"
测试输入结果,比较两个命令的不同:
./TestEchoArgs.sh "a b c" 'd e' f g 输出: ./EchoArgs:'a''b''c''d''e''f''g' ./EchoArgs:'a''b''c''d''e''f''g' ./EchoArgs:'a b c d e f g''?''?''?''?''?''?' ./EchoArgs:'a b c''d e''f''g''?''?''?'
分析:
./EchoArgs $* ./EchoArgs $@ 前两个没放在""中,结果一样,因为$*和$@的执行之后都是传给EchoArgs由空格分隔的七个参数 ./EchoArgs "$*" 由于$*不能分辨有空格的参数,最后传给EchoArgs的只有一个""的参数 ./EchoArgs "$@" $@在""中分辨出有四个参数,前两个参数中有空格。
$# - 参数个数
shift $#可以去掉所有的传入参数。
$$ - 当前进程的ID
由于进程的ID都是不同的,这个变量可以用来命名唯一的临时文件。例如下面这个脚本,返回行数:
#!/bin/sh # ************************************** # usage: # count lines of input file/files # ************************************** tempfile=/tmp/$0.$$ for i in $@ do if [ -f $i ]; then cat $i >> $tempfile fi done echo `wc -l $tempfile` lines were found /bin/rm $tempfile
另一个用处是,可以在其他进程中通过$$来kill这个进程。例如:
echo $$ >/tmp/job.pid kill -HUP `cat /tmp/job.pid`
$! - 后台进程的PID
只有运行&命令的进程才会改变$!.使用此命令可以控制多个后台运行的程序,比如:
#!/bin/sh job1 & pid=$! job2 & pid="$pid $!" job3 & pid="$pid $!" trap "kill -15 $pid" 0 1 2 15 wait
$? - 错误状态
返回前一个程序的退出状态。
----------
未完,不定时更新...
Last updated - 2/23/2016
相关文章推荐
- 关于循环语句中的几个需要注意的地方
- VC++编程需要注意的地方(请大家积极回复)
- 使用proguard需要注意的几个地方
- 引用计数需要注意的几个地方
- 【读书笔记】并发编程需要注意的几个典型问题
- spring 3.0 中 @Scheduled cron表达式需要注意的几个地方
- access中使用SQL语句需要注意的几个地方
- 将鼠标指针修改为自定义图片需要注意的几个地方
- ios编程需要注意的地方
- HTML 几个需要注意的地方
- VS2008开发MOSS工作流几个需要注意的地方
- VS2008开发MOSS工作流几个需要注意的地方
- Oracle分析函数model使用时需要注意的几个地方(二)
- vc 编程最需要注意的地方
- GDI编程需要注意的地方(句柄泄漏)
- Lora程序设计需要注意的几个地方
- access中使用SQL语句需要注意的几个地方
- 冷启动与热启动在STM32基于RTOS编程中需要注意的地方
- 【摘录】Ubuntu 10.10编译Android froyo可能需要注意的几个地方
- iOS开发笔记(六):UIButton需要注意的几个地方