x

Bash编程技巧的简明文档

2023-01-23 14:24:50编辑:阿七

接下来的几个,我自己写shell代码的时候,用喜欢的几个写法扔玉。

检查命令执行是否成功

第一种写法比较常见:

Bash编程技巧的简明文档

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

更多排行: