我试图:
- 接受 bash 中的输入并存储它逐字到一个文件
- 猫文件的内容。
还应写入任何特殊字符逐字到文件。
输入样本
./verbatim.sh -a smb 'ngrep -i -d $INTERFACE 's.?a.?m.?b.?a.*[[:digit:]]''
预期产出
-a smb 'ngrep -i -d $INTERFACE 's.?a.?m.?b.?a.*[[:digit:]]''
实际产量
内部引号被删除
-a smb 'ngrep -i -d $INTERFACE s.?a.?m.?b.?a.*[[:digit:]]'
代码
#!/bin/bash
#
# Script Name: verbatim.sh
chars='[ !"#$&()*,;<>?\^`{|}]'
for arg
do
if [[ $arg == *\'* ]]
then
arg=\""$arg"\"
elif [[ $arg == *$chars* ]]
then
arg="'$arg'"
fi
allargs+=("$arg") # ${allargs[@]} is to be used only for printing
done
printf '%s\n' "${allargs[*]}" > /tmp/pse.tmp
cat /tmp/pse.tmp
我不确定 bash 是否可以完成我的要求?
使用 read 或 IFS 会更好吗?我的脚本的目标是将用户的输入附加到一个文件中,该文件将用作特定服务的“快速参考”。
答案1
关于标题的问题
一旦变量包含特定字符串,它就不会被再次扩展(如果引用)。
因此,对于您提出的示例案例(全部转换'
为'\''
):
var='-a smb '\''ngrep -i -d $INTERFACE '\''s.?a.?m.?b.?a.*[[:digit:]]'\'''\'''
或者,减少一点(实际上不需要,但最好删除 Continuous ''
):
var='-a smb '\''ngrep -i -d $INTERFACE '\''s.?a.?m.?b.?a.*[[:digit:]]'\'\'
将打印这个(你想要的字符串):
$ echo "$var"
-a smb 'ngrep -i -d $INTERFACE 's.?a.?m.?b.?a.*[[:digit:]]''
并会给脚本提供相同的字符串:
$ ./verbatim.sh "$var"
如果 ( verbatim.sh
) 脚本是:
#!/bin/bash
printf '<%s>' "$@"; echo
它将打印:
$ ./verbatim.sh "$var"
<-a smb 'ngrep -i -d $INTERFACE 's.?a.?m.?b.?a.*[[:digit:]]''>
您所写内容的逐字字符串。
写入文件:
如果您想将该输入写入文件,可以将verbatim.sh
脚本扩展为:
#!/bin/bash
printf '<%s>' "$@"; echo
printf '%s\n' "$var" > /tmp/pse.tmp
进而:
$ cat /tmp/pse.tmp
-a smb 'ngrep -i -d $INTERFACE 's.?a.?m.?b.?a.*[[:digit:]]''
会给你你所要求的输出。
问题
上面的方法之所以有效,是因为我一直小心地将“$var”内的字符串处理为单身的字符串,而不是参数。
您的脚本要做的第一件事是要求提供以下参数列表:
for arg do .......
只有一个参数:一个字符串。如果您需要参数列表,则过程必须完全不同。
然后,您尝试用双引号或单引号引用每个单独的参数。不,那也行不通。
而且,阅读您提供的字符串的内容,您似乎正在尝试构建一个命令并执行它。那就更糟了。你必须读我试图将命令放入变量中,但复杂的情况总是失败!
然后,也许可以编辑这个问题以使用数组作为参数。
答案2
这不可能。
如果您运行以下命令
myprog a
myprog \a
myprog "a"
myprog 'a'
那么在所有 4 种情况下,第一个参数获得的值myprog
将是一个指向 string 的指针"a"
,并且您无法分辨给了哪个。因此,您无法逐字写出所给的内容,这是因为参数myprog
甚至在调用之前就已被处理。