接下来的几个,我自己写shell代码的时候,用喜欢的几个写法扔玉。
检查命令执行是否成功
第一种写法比较常见:
echo abcdee | grep -q abcd
if [ $ -eq 0 ]; then
echo 'Found '
else
echo 'Not found '
fi
简洁的写法:
if echo abcdee | grep -q abc; then
echo 'Found '
else
echo 'Not found '
fi
当然可以不使用if/else,但可读性很差:
[ sunnov 0405:58am ] [ ko dango @ devo PS ]~/workspace
$ echoabcdee-qabcecho ' found '|echo ' not found '
福登
将标准输出和标准错误输出重定向至/dev/null
第一种写法比较常见:
grep 'abc' test.txt 1/dev/null 21
常见错误写法:
grep 'abc' test.txt 21 1/dev/null
简洁的写法:
grep 'abc' test.txt /dev/null
使用awk
举一个实际的例子,获取Xen DomU的id。
常见写法:
sudo xmli|grep VM _ name|awk ' {打印$2} '
简洁的写法:
sudo XM Li|awk '/VM _ name/{打印$2} '
用逗号连接一个文本的所有行
假定文件内容如下:
[ sat nov 0310:04pm ] [ ko dango @ devo PS ]~/workspace
$ cat /tmp/test.txt
1
2
3
使用sed命令:
[ sat nov 0310:14pm ] [ ko dango @ devo PS ]~/workspace
$ sed ':a; $! n; s/n/; ta' /tmp/test.txt
一二三
简洁的写法:
[ sat nov 0310:04pm ] [ ko dango @ devo PS ]~/workspace
$ paste -sd,/tmp/test.txt
一二三
过滤重复行
假定文件内容如下:
[ sat nov 0310:16pm ] [ ko dango @ devo PS ]~/workspace
$ sort /tmp/test.txt
1
1
2
3
常用方法:
[ sat nov 0310:16pm ] [ ko dango @ devo PS ]~/workspace
$ sort /tmp/test.txt | uniq
1
2
3
简单的写法:
[ sat nov 0310:16pm ] [ ko dango @ devo PS ]~/workspace
$ sort /tmp/test.txt -u
1
2
3
grep检索词
假设文本的每一行都有一个ip地址。 范例
[ sat nov 0310:20pm ] [ ko dango @ devo PS ]~/workspace
$ cat /tmp/ip.list
10.0.0.1
10.0.0.12
10.0.0.123
使用grep确定是否包含名为10.0.0.1的ip地址。
常见写法:
[ sat nov 0310:22pm ] [ ko dango @ devo PS ]~/workspace
$ grep '10.0.0.1' /tmp/ip.list
10.0.0.1
简单的方法(其实这个方法并不一定简单,但它有助于解释-w这个参数)
[ sat nov 0310:23pm ] [ ko dango @ devo PS ]~/workspace
$ grep -w '10.0.0.1' /tmp/ip.list
10.0.0.1
顺便说一下,grep的-n/-H/-v/-f/-c参数很有用。
临时设置环境变量
常见写法:
[ sat nov 0310:26pm ] [ ko dango @ devo PS ]~/workspace
$ export LC_ALL=zh_CN.UTF-8
[六11月0310点26分下午] [kodango@devops] ~/workspace
$ date
2012年11月03日星期六22点26分55CST
简洁的写法:
[六11月0310点26分下午] [kodango@devops] ~/workspace
$ unset LC_ALL
[ sat nov 0310:27pm ] [ ko dango @ devo PS ]~/workspace
$ LC_ALL=zh_CN.UTF-8 date
2012年11月03日星期六22点27分43CST
在指令之前添加环境变更的设定,只需暂时变更当前执行指令的环境即可。
使用位置参数,例如$1,$2.
假设您只想要使用$2,$3.几个参数。 一般做法如下。
shift
echo '$@ '
为什么不那样写呢?
echo '${@:2} '
然后,求出下面的写法
我认为有这样的需求,但是如果没有提供一个参数值,可以使用默认值。
常见的写法是:
arg=$1
if [ -z '$arg' ]; then
arg=0
fi
简洁的写法是这样的:
arg=${1:-0}
bash特殊参数---的使用方法
要确定grep中的字符串是否包含-i,请尝试执行以下操作:
[ sat nov 0310:45pm ] [ ko dango @ devo PS ]~/workspace
$ echo 'abc-i' | grep '-i '
usage:grep [ option ] . pattern [ file ] .
try ' grep-- help ' for more information。
[ sat nov 0310:45pm ] [ ko dango @ devo PS ]~/workspace
$ echo 'abc-i' | grep '-i '
abc-i
简洁的方法如下
[ sat nov 0310:45pm ] [ ko dango @ devo PS ]~/workspace
$ echo 'abc-i' | grep -- -i
abc-i
bash中--后面的参数不会作为选项进行分析。
函数返回值缺省为最后一条语句的返回值
# Check whether an item is a function
# $1: the function name
# return:0 (是) or1 )否)
function is_function ( )
{
local func_name=$1
test ' ` type-t $ 12/dev/null ` '=' function '
}
不要画蛇添足,在后面添加return $。
将printf格式的结果指定给变量
例如,如果将数字转换为十六进制格式,则常见格式如下:
[ sat nov 0310:55pm ] [ ko dango @ devo PS ]~/workspace
$ var=$(printf '%%x' 111 )
简单的写法是:
[ sat nov 0310:54pm ] [ ko dango @ devo PS ]~/workspace
$ printf -v var '%%x' 111
请看printf的帮助
[ sat nov 0310:53pm ] [ ko dango @ devo PS ]~/workspace
$ help printf | grep -A 1 -B 1 -- -v
printf:printf [-vvar ] format [ arguments ]
格式sandprintsargumentsundercontroloftheformat。
--
Options :
- vvarassigntheoutputtoshellvariablevarratherthan
显示为on the standard output
打印文件行
打印文件的第一行:
head -1 test.txt
打印文件的第二行:
sed -n '2p' test.txt
打印文件的第2-5行:
sed-n ' 2,5p ' test.txt
从文件的第二行开始打印包含第二行的第五行的内容。
sed-n ' 2,4p ' test.txt
打印倒数第二行:
$ tail -2 test.txt | head -1
$ tac test.txt | sed -n '2p '
let或() ) )命令进行算术运算
如何运算一个数字,你可能会这样使用:
a=1
a=`expr a 1 `
为什么你不需要知道:
a=1
雷特a
let a=2
获取在软连接中指定的实际文件名
如果你不知道的话,你可能会这样取得:
[ sat nov 0311:12pm ] [ ko dango @ devo PS ]~/workspace
$ ls-l/usr/bin/python|awk-f '-' {打印$2} '|tr-d ' '
/usr/bin/python2
如果你知道有readlink这个命令,就会变成。
[ sat nov 0311:13pm ] [ ko dango @ devo PS ]~/workspace
$ readlink /usr/bin/python
/usr/bin/python2
获取一个字符的ASCII码
[ sat nov 0311:14pm ] [ ko dango @ devo PS ]~/workspace
$ printf 'x ' ' '
2b
[ sat nov 0311:30pm ] [ ko dango @ devo PS ]~/workspace
$ echo -n ' ' | od -tx1 -An | tr -d ' '
2b
清空文件
一般用法:
echo '' test.txt
简单的写法:
test.txt
请不要忘记有here document
以下代码:
grep-v1/tmp/test.txt|while readline; do
雷特a
Echo----$line----
唐
echo a:$a
执行后有什么问题吗?
[ sunnov 0405:35am ] [ ko dango @ devo PS ]~/workspace
$ sh test.sh
---2----2
---3----
a :
我发现a这个变量没有被赋值。 为什么会这样呢? 管道后面的代码在子shell中执行,因此更改不影响当前shell。 当然,a这个变量没有赋值。
改变想法的话,可以做以下事情。
grep-v1/tmp/test.txt/tmp/test.tmp
while read line; do
雷特a
Echo----$line----
done /tmp/test.tmp
echo a:$a
rm -f /tmp/test.tmp
但是多了一个临时文件。 最后删除。
这里可以使用here document :
while read line2; do
let b
echo $line2
done EOF
` grep -v 1 /tmp/test.txt `
EOF
echo b: $b
here document经常用于需要输出大文本的地方,例如脚本的help函数。
删除字符串的第一个或最后一个字符
假设字符串如下:
[ sunnov 0410:21am ] [ ko dango @ devo PS ]~/workspace
$ str='aremoveb '
最初的想法可能是通过sed或其他命令实现这个功能,但实际上有一个简单的方法。
[ sunnov 0410:24am ] [ ko dango @ devo PS ]~/workspace
$ echo '${str# } '
移除
[ sunnov 0410:24am ] [ ko dango @ devo PS ]~/workspace
$ echo '${str% } '
aremove
同样,也可以删除2个、3个、4个……
有一次删除第一个和最后一个字符的方法吗? 答案当然是肯定的:
[ sunnov 0410:26am ] [ ko dango @ devo PS ]~/workspace
$ echo '${str:1:-1} '
移除
bash的man文档中有关于替换这些变量的说明。
使用逗号join数组元素
假设数组元素中没有空间,可以使用此方法。
[ sunnov 0410:14am ] [ ko dango @ devo PS ]~/workspace
$a=(1)2)3) )。
$ b='${a[*]}
[ sunnov 0410:15am ] [ ko dango @ devo PS ]~/workspace
$ echo ${b///,}
一二三
注:如果此数组的长度非常长,则使用此替换会导致时间开销高,性能差,因此建议使用sed。
假设数组元素包含空格,则可以使用printf命令执行以下操作:
[ sunnov 0410:15am ] [ ko dango @ devo PS ]~/workspace
$a=(1)2)3)4) ) ) ) ) ) ) ) ) )。
[ sunnov 0410:15am ] [ ko dango @ devo PS ]~/workspace
$ printf ',%s' '${a[@]}' | cut -c2-
一二三四
壳内的多进程
在命令行中,在命令行后面加上符号,使命令在后台执行。 在shell脚本中,可以使用“( cmd )”使fork运行一个子shell。
可以利用这两点实现shell的多线程。
job_num=10
function do_work (
{
echo 'Do work . '
}
for ( ) I=0; i job_num; I ) ); do
echo 'Fork job $i '
( do_work )
唐
wait # wait for all job done
echo 'All job have been done!'
请注意最后的wait命令。 其作用是等待所有子进程结束。
有几个小技巧:
1 ) sudo iptables -L -n | vim -
2 ) grep -v xxx | vim -
3 ) echo $'”
4 ) set -- 1 2 3; echo '$@ '
5 )搜索堆栈覆盖/用户等站点
6 ) VIM编辑远程文件vim scp://xxx//etc/vimrc
7 )远程执行脚本ssh xxx bash xxx.sh