bash字符串前美元符号的作用

Posted by on November 30, 2014
本文阅读量:

bash是由内置变量IFS作为字段分隔符,IFS变量的值直接影响脚本如何解析参数,其默认值为\<space\>\<tab\>\<newline\>, 即空格、制表符以及换行符。 遇到一个需求是需要设置分隔符为换行符\n, 即一行一个字段,空格和制表符不会分割字段。很容易想到的办法是重设IFS变量值:

OLD_IFS=$IFS
IFS='\n'
# do some work here
IFS=$OLD_IFS

但结果并非所期望的,bash会把IFS的单独的每个字符当作了分隔符,即分隔符被设置成下划线\ 和字母n,而不是\n

通过google搜索,得知需要把\n转化成ANSI-C Quoting, 解决办法是把字符串放入$’string’中,即设置为:

IFS=$'\n'

顺便搜了下$字符在shell字符串的用途,在what-does-it-mean-to-have-a-dollarsign-prefixed-string-in-a-script中详细介绍了字符串前面加$字符的两种形式,一种是使用单引号,另一种是使用双引号,这二者的区别为:

There are two different things going on here, both documented in the bash manual

$’

Dollar-sign single quote is a special form of quoting: ANSI C Quoting Words of the form $’string’ are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.

$”

Dollar-sign double-quote is for localization: Locale translation A double-quoted string preceded by a dollar sign (‘$’) will cause the string to be translated according to the current locale. If the current locale is C or POSIX, the dollar sign is ignored. If the string is translated and replaced, the replacement is double-quoted.

因此单引号表示转化成ANSI-C字符,双引号则表示将字符串本地化。

以下是一个实例,ping /etc/hosts的主机名为video-开头的主机名,检查网络状况!

  #!/bin/bash
trap "echo 'interrupted!';exit 1" SIGHUP SIGINT SIGTERM
OLD_IFS=$IFS
IFS=$'\n'
for i in `awk '$0!~/^$/ && $0!~/^#/ && $2~/^video/ {print $1,$2}' /etc/hosts`
do
	ADDR=$(echo $i | cut -d' ' -f 1)
	DOMAIN=$(echo $i | cut -d' ' -f 2)
	if ping -c 2 $ADDR &>/dev/null
	then
		echo $DOMAIN ok!
	else
		echo $DOMAIN off-line!
	fi
done
IFS=$OLD_IFS