「Shell」- 快速入门及简单示例

  CREATED BY JENKINSBOT

定义变量

变量转义

这是别人在群里问到的一个问题。看如下命令:

ssh localhost "/bin/cat > /tmp/tmp << eof
\\\$demo
eof"

上述命令生成的/tmp/tmp文件的内容是$demo,为什么?首先,传给SSH的命令在双引号中,所以Bash先解析一次,但是它解析了”\\“和”\$“两个组合。也就是说,SSH拿到手的时候,命令已经变成”\$name“。即:

/bin/cat > /tmp/tmp << eof
\$demo
eof

那么,写入文件的自然就是”$name“字符串。

换句话说,下面的写法是等效的:

ssh localhost '/bin/cat > /tmp/tmp << eof
\$dddd1
eof

变量引用

定义了一个SHELL函数:

ddPATH="-cp /mnt/demo"
debug=com.k4nz.Enter

debug()
{
	java $ddPATH "$USER_FLAGS" $debug
}

而USER_FLAGS使用用户自定义的,可能存在,也可能不存在。在执行这个函数的时候会产生如下错误:

Error: Could not find or load main class

我们尝试打印出要执行的命令,所以对函数作出如下修改,加了一个echo命令:

ddPATH="-cp /mnt/demo"
debug=com.k4nz.Enter

debug()
{
	echo java $ddPATH "$USER_FLAGS" $debug
}

该函数的输入如下:

java -cp /mnt/demo  com.k4nz.Enter

在命令行里执行这个命令是没有错误,完全可以正常执行这个类,这就见鬼了。

其实,有的时候就是需要非常仔细的观察,问题的关键就在于那个”$USER_FLAGS”,修改成$USER_FLAGS就正常了。为什么?

由于USER_FLAGS未定义,函数里的java $ddPATH “$USER_FLAGS” $debug命令执行前,SHELL会先进行解析,而解析的结果是java -cp /mnt/demo “” com.k4nz.Enter,而echo的结果是java -cp /mnt/demo com.k4nz.Enter,这两个并不等价。而当我们把函数里的命令修改成java $ddPATH $USER_FLAGS $debug后,解析的结果就与echo等价了,这时候也不会出现那个错误了。

在变量中嵌入换行符号

Trying to embed newline in a variable in bash [duplicate]

该部分将介绍如何在BASH的变量中嵌入换行符号。

方法一、直接插入 \n 序列:

p="var1\nvar2"
echo -e "${p}"

# echo 命令的 -e 选项会将变量中的 \n 序列解释为换行符。

方法二、变量定义时插入换行符:

p="var1
var2"
echo "${p}"

# 在这种情况下,使用echo输出的变量必须使用双引号。如果未使用,则输出结果为:var1 var2

方法三、使用 $’\n’ 序列:

p="var1"$'\n'"var2"
echo "${p}"

# BASH 会将$'\n'解释为一个换行符号。
# 在这种情况下,使用echo输出的变量必须使用双引号。如果未使用,则输出结果为:var1 var2

定义函数

How do I unset or get rid of a bash function?
执行命令:unset -f function_name

# 显示当前Shell正在执行的命令

-「How to echo shell commands as they are executed
展开变量并在行前打印加号:set -xset -o xtrace
在打印之前,并不展开变量:set -vset -o verbose

# 当遇到错误时立即退出

-「bash: Trap error and exit
在执行脚本时,遇到错误立即退出:set -e

How to add arithmetic variables in a script

How to add arithmetic variables in a script

以下是几种不同的写法,以及各自的兼容性:

# portable but slow
a=`expr "$a" + "$num"`

# POSIX and portable except to the Bourne shell and earlier versions of the Almquist shell
a=$(($a+$num))

# require ksh, bash or zsh
((a=a+num))

let a=a+num

((a+=num))