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

Bash script - string with spaces in argument used for call tshark in script

提问人:gsmgxm 提问时间:10/21/2022 最后编辑:gsmgxm 更新时间:10/21/2022 访问量:100

问:

decode_bip_MCShark.sh:

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

运行命令

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 蝙蝠文件:

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

在此 Windows bat 中,%~4 替换 %4.

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

bash 参数传递 空格

评论


答:

1赞 chrslg 10/21/2022 #1
cd "$1"
echo tshark -r "$2" -Y "$3" $4 -T fields
tshark -r "$2" -Y "$3" $4 -T fields

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

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

所以当你打电话时

myscript foo bar "hello world"

里面,1 美元是,2 美元是,3 美元是。 因此,如果 myscript 反过来调用myscriptfoobarhello world

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 中,$1 是 ,$2 是 和 $3 是 所以,变量替换发生,我的 printf 变成foobar"hello world"

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

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

底线是:使用直引号很少是一个好主意(我的意思是,除非它们是文本的一部分,例如“不要”或“不能”),即引号内的引号或转义引号。 我不,他们从来都不是。但绝大多数情况下,当你这样做时,这意味着你做错了什么,在某些情况下它会失败,并且有更好的解决方案。

评论

1赞 glenn jackman 10/21/2022
另外,不要同时使用单引号和双引号传递参数:只有一个或另一个。
0赞 chrslg 10/21/2022
是的。我想知道这些是否是解决问题的另一种尝试,其中这些引号是针对 tshark 的
0赞 gsmgxm 10/21/2022
tshark -r A.pcap -Y "3gpp.subcellid == 0 && Length != 0x00000000" -e UlData_detectedPrachPreambles_t.prachPreambleIndex -e UlData_detectedPrachPreambles_t.initialTa -T fields是一个工作命令。,这个不行。-----------------------------------------------------------------------------------------tshark -r A.pcap -Y 3gpp.subcellid == 0 && Length != 0x00000000 -e UlData_detectedPrachPreambles_t.prachPreambleIndex -e UlData_detectedPrachPreambles_t.initialTa -T fields
0赞 gsmgxm 10/21/2022
解决方案的结果如下所示:tshark -r /home/ute/22R4_CNI81085_UL-Connection_FDD_CPRI_ABIL_AREA_FR1_PRACH-5M-SNR-5_UL_bip_log.pcap -Y "3gpp.subcellid == 0 && Length != 0x00000000" -e UlData_detectedPrachPreambles_t.prachPreambleIndex -e UlData_detectedPrachPreambles_t.initialTa -T fields -------------------------------------------------------- tshark: Some fields aren't valid: UlData_detectedPrachPreambles_t.prachPreambleIndex -e UlData_detectedPrachPreambles_t.initialTa
0赞 gsmgxm 10/21/2022
echo 输出和以前一样(我的输出),但 tshark 响应现在它可以识别第一个 -e 参数,但仍然认为第二个 -e 参数是第一个 -e 参数的一部分,它认为只有一个 -e 参数。