eval
、exec
、bash -c
等命令的笔记和比较。
eval
将参数 当作shell 脚本进行执行(Execute arguments as a shell command.)
1
2
3
~$ CD="cd Desktop"
~$ eval $CD
~/Desktop$
逃脱字符
像 SQL注入SQL injection 一样,eval
可以逃脱。
1
2
3
4
5
$ cmd=("kyakya"); eval "echo hello world,"${cmd[*]}""
hello world,kyakya
$ cmd=("hacker;date"); eval "echo hello world,"${cmd[*]}""
hello world,hacker
2021年 5月 19日 水曜日 01:40:10 JST
exec
使用给定的命令,代替 当前的shell。(Replace the shell with the given command. )
1
2
3
4
5
$ bash -c "exec echo 1;echo 2"
1
$ bash -c "eval echo 1;echo 2"
1
2
示例:
- https://github.com/panubo/docker-sshd/blob/master/entry.sh
bash -c
bash -c
文档是这样解释的:来源
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.
bash -c
是开启 新的shell(subshell) ,然后执行命令的
bash -c vs eval
eval
是在 当前shell 下执行命令,所以会继承所有内容;bash -c
不继承stackoverflow
- local variable
- functions
- options
- traps
- etc
1
2
3
4
5
6
$ cat ./test_bash.sh
bash -c "$1" # 'bash -c'命令结束时,'bash -c'所处的shell消失,本地变量也随着消失
echo "$var"
$ bash ./test_bash.sh var=xxx
$ # 结果为空白
1
2
3
4
5
$ cat ./test_eval.sh
eval "$1"
echo "$var"
$ bash ./test_eval.sh var=xxx
xxx
参考:
- https://unix.stackexchange.com/questions/124590/variable-as-command-eval-vs-bash-c
eval vs source
eval
和 source
的原理是一致的,区别:
source
: Read and execute commands from the filename argument in the current shell context. [man bash](运行的一般是文本)eval
:Execute arguments as a shell command. (运行的一般是单个命令)
Notice 注意
当使用 eval
与 exec
等命令创建自定义函数时,不要使用 echo
等标准输出命令
1
2
3
4
5
6
7
8
function aws(){
echo "begin" #不要这样做
eval "/usr/local/bin/aws $cmd_str" "$@"
}
# echo 输出的内容,将会导致管道的下一个命令启动。
$ aws xxx | grep begin
begin