Bash 脚本 - 参数中带有空格的字符串,用于在脚本中调用 tshark



>decode_bip_MCShark.sh:

cd $1
echo tshark -r $2 -Y $3 $4 -T fields
tshark -r $2 -Y $3 $4 -T fields
>run 命令
sh decode_bip_MCShark.sh /home/ute/ A.pcap '"3gpp.subcellid == 0 && Length != 0x00000000"' '-e UlData_detectedPrachPreambles_t.prachPreambleIndex -e UlData_detectedPrachPreambles_t.initialTa'

结果:

tshark -r A.pcap -Y "3gpp.subcellid == 0 && Length != 0x00000000" -e UlData_detectedPrachPreambles_t.prachPreambleIndex -e UlData_detectedPrachPreambles_t.initialTa -T fields
tshark: Display filters were specified both with "-Y" and with additional command-line arguments.

直接运行命令:

tshark -r A.pcap -Y "3gpp.subcellid == 0 && Length != 0x00000000" -e UlData_detectedPrachPreambles_t.prachPreambleIndex -e UlData_detectedPrachPreambles_t.initialTa -T fields

结果无错误


我有一个可以在Windows系统下工作的Windows bat文件:

cd %1
tshark -r %2 -Y %3 %~4  -T fields

在此窗口中,%~4 替换 %4。

现在在 Linux shell bash,如何获得相同的功能?

cd "$1"
echo tshark -r "$2" -Y "$3" $4 -T fields
tshark -r "$2" -Y "$3" $4 -T fields

Bash不是一种常见的语言。乍一看,它看起来有点像任何其他语言,带有循环、函数、变量等。但也有一些主要区别。而与逃避、引号等作斗争,是没有意识到这些差异的一个症状。除了花时间阅读和理解它是如何工作的之外,没有其他治疗方法。计算机中的许多东西都可以通过示例,模仿,然后概括来学习。但这不会削减抨击。我知道很多人能够写出 1000 行 bash,但谁会为这些引号而苦恼,随机调整它们的位置和删除它们的位置,随机添加,在它意外开始工作之前几个小时。

特别是,在这种情况下,需要理解的一个重要点是变量替换。在 bash 中,变量(还有模式、子壳的结果等。并且对于给定的顺序,重要的是要知道)在命令执行之前在命令行中替换。

所以当你打电话

myscript foo bar "hello world"

myscript内部,1美元是foo,2美元是bar,3美元是hello world。 所以,如果 myscript 依次调用

printf "<%s>n" $1 $2 $3

(为每个 printf 参数打印一行) $x首先被它们的值所取代,因此真正执行的是

printf "<%s>n" foo bar hello world

然后,拆分命令行参数并删除引号

然后将该命令拆分(单词拆分)为

command printf, with arguments
"<%s>n"
foo
bar
hello
world

命令行中的引号被删除,因此

printf
<%s>n
foo
bar
hello
wolrd

执行哪个,导致结果

<foo>
<bar>
<hello>
<world>

如果你试图通过在初始参数中添加额外的引号层来解决这个问题,那就更复杂了。

./myscript foo bar '"hello world"'

将导致,在 Myscript 中,foo1 美元,bar2 美元,"hello world"3 美元 所以,变量替换发生,我的printf变成

printf "<%s>n" foo bar "hello world"

然后,发生单词拆分。这很棘手:拆分会考虑在先前替换之后存在的所有空格,但没有出现在引号之间。 但是这些引号必须在替换之前存在(否则引号之间不会出现空格)。

(换句话说,由于替换而出现的空格会影响单词拆分,但因替换而出现的引号不会)

因此,命令被拆分为

printf
"<%s>n"
foo
bar
"hello
world"

删除引号后(命令行中的引号,因此不是"helloworld"中的引号)

printf
<%s>n
foo
bar
"hello
world"

因此结果

<foo>
<bar>
<"hello>
<world">

所以,你要做的是

./myscript foo bar "hello world"

但是,进入myscript,以确保如果出现一些空格,3美元中的内容不会被拆分为单独的单词,

printf "<%s>n" "$1" "$2" "$3"

这样,$1foo$2bar$3hello world。 变量替换后,您得到

printf "<%s>n" "foo" "bar" "hello world"

分词后(不考虑引号之间出现的空格)

printf
"<%s>n"
"foo"
"bar"
"hello world"

删除报价后

printf
<%s>n
foo
bar
hello world

有结果

<foo>
<bar>
<hello world>

不出所料。

所以,很简单。但前提是您牢记发生的连续替换。

如果您需要将可变数量的额外参数传递给tshark,我认为最明智的方法是将可变数量的额外参数传递给您的脚本。

cd "$1"
rArg="$2"
YArg="$3"
shift 3
echo tshark -r "${rArg}" -Y "${YArg}" "$@" -T fields
tshark -r "${rArg}" -Y "${YArg}" "$@" -T fields

然后调用脚本

bash decode_bip_MCShark.sh /home/ute/ A.pcap '3gpp.subcellid == 0 && Length != 0x00000000' -e UlData_detectedPrachPreambles_t.prachPreambleIndex -e UlData_detectedPrachPreambles_t.initialTa

然后,如果需要,您甚至可以引用一些额外的参数,同时仍然将它们作为单独的参数。

底线是:使用字面引号很少是一个好主意(我的意思是,除非它们是文本的一部分,例如"不要"或"不能"),即引号中的引号或转义引号。 我不认为他们永远不会。但压倒性地,当你这样做时,这意味着你做错了什么,在某些情况下它会失败,并且有一个更好的解决方案。

最新更新