alias
脚本中不能使用
问题描述
在脚本中定义alias
并使用, 报错;
$ cat dd.sh
#!/bin/bash
bash -c $'alias aaa="ls -l";aaa;'
$ ./dd.sh
bash: line 1: aaa: command not found
问题分析
https://www.gnu.org/software/bash/manual/html_node/Aliases.html
原文描述; alias
不在非交互式命令行中展开, 也就是说, 使用脚本默认不进行扩张; 即aaa
没有扩张成ls -l
;
但是也提供了打开机制; shopt -s expand_aliases
启用即可;
修改后再执行
$ cat dd.sh
#!/bin/bash
bash -c $'shopt -s expand_aliases;alias aaa="ls -l";aaa;'
$ ./dd.sh
bash: line 1: aaa: command not found
仍然无法执行,why?
再次分析
上面链接有一段话;
Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read.
即alias
不是执行时扩张,而是读取一行一起处理, 也就是说要换行才会触发;那么在指令aaa
之前加个换行符试试;
再次修改
$ cat dd.sh
#!/bin/bash
bash -c $'shopt -s expand_aliases;alias aaa="ls -l";\naaa;'
$ ./dd.sh
total 24
-rwxrwxr-x 1 ch ch 16320 Mar 1 14:03 a.out
-rwxrw-r-- 1 ch ch 72 Mar 4 01:42 dd.sh
-rw-rw-r-- 1 ch ch 1292 Feb 6 12:27 test.c
成功执行!
字符串里面嵌套多个单引号;
问题描述;
同一行里需要多个单引号
$ cat dd.sh
#!/bin/bash
bash -c $'eval $\'shopt -s expand_aliases;alias aaa=\'ls -l\';\naaa;\''
$ ./dd.sh
bash: line 1: alias: -l: not found
a.out dd.sh test.c
问题分析
转义字符分析错误;
上面的扩张结果是
eval $'shopt -s expand_aliases;alias aaa='ls -l';\naaa;'
也就是说这时的$''
提前形成了配对, 那么还进行转移就需要再添加\
$ cat dd.sh
#!/bin/bash
bash -c $'eval $\'shopt -s expand_aliases;alias aaa=\\\'ls -l\\\';\naaa;\''
$ ./dd.sh
total 24
-rwxrwxr-x 1 ch ch 16320 Mar 1 14:03 a.out
-rwxrw-r-- 1 ch ch 88 Mar 4 01:52 dd.sh
-rw-rw-r-- 1 ch ch 1292 Feb 6 12:27 test.c
解决方案二
上面看到了一种解决方案, 但是太垃圾了; 下面看看更垃圾的;
$ ./dd.sh
./dd.sh: line 2: alias: -l': not found
./dd.sh: line 2: naaa: command not found
./dd.sh: line 2: : command not found
$ cat dd.sh
#!/bin/bash
bash -c 'eval $'shopt -s expand_aliases;alias aaa=\'ls -l\';\naaa;'
改进一下, 拼接;
#!/bin/bash
bash -c 'eval $' "'" 'shopt -s expand_aliases;alias aaa=' "'" 'ls -l' "'" ';\naaa;'
上面的可以看到是多个字符串, 但是他们之间有空格, 解析会出错, 所以我们需要去掉空格;
#!/bin/bash
bash -c 'eval $'"'"'shopt -s expand_aliases;alias aaa='"'"'ls -l'"'"';\naaa;'
还是有错误, 因为扩张后的结果是这样的;
eval $'shopt -s expand_aliases;alias aaa='ls -l';\naaa;
那就再加个后缀'
, 但是问题是'ls -l'
处的单引号造成了终止; 加个转移即可
$ cat dd.sh
#!/bin/bash
bash -c 'eval $'"'"'shopt -s expand_aliases;alias aaa=\'"'"'ls -l\'"'"';\naaa;'"'"
$ ./dd.sh
total 24
-rwxrwxr-x 1 ch ch 16320 Mar 1 14:03 a.out
-rwxrw-r-- 1 ch ch 95 Mar 4 02:01 dd.sh
-rw-rw-r-- 1 ch ch 1292 Feb 6 12:27 test.c