问题描述
我有一个包装脚本,用于编译命令来计算执行命令的 md5sum 和时间(还有一些其他的东西)。重点是我必须在包装脚本中计算 md5sum。
问题是 m5sum 为 gcc main.c
和 gcc "main.c"
返回相同的输出,但命令不同。
这是简单的代码。
$ cat sc.sh
#!/usr/bin/env bash
cmd="$@"
cmdh=$(echo "$cmd" | md5sum - | cut -f1 -d" ")
echo "CMD ${cmd}"
echo "MD5 ${cmdh}"
time $@
$ ./sc.sh gcc -c main.c -o out
CMD gcc -c main.c -o out
MD5 b671a0f3b1235aa91e5f86011449c698
real 0m0.019s
user 0m0.009s
sys 0m0.010s
这是第二个。我想要不同的 md5sum。
$ ./sc.sh gcc -c "main.c" -o out
CMD gcc -c main.c -o out
MD5 b671a0f3b1235aa91e5f86011449c698
real 0m0.017s
user 0m0.007s
sys 0m0.011s
喜欢这里:
$ echo 'gcc -c "main.c" -o out' | md5sum - | cut -f1 -d" "
94d2bafbec690940d1b908678e9c9b7d
$ echo 'gcc -c main.c -o out' | md5sum - | cut -f1 -d" "
b671a0f3b1235aa91e5f86011449c698
用 bash 可以做到吗?不将它绑定到任何特定的 bash 版本会很棒,但如果没有其他选择,那也不错。
解决方法
内部脚本 gcc main.c
和 gcc "main.c"
是相同的命令。
两种变体中的 $0 = gcc
和 $1 = main.c
。
你在内部看不到差异,脚本也不能做出不同的标志,所以你没有理由看到这一点。
,在解析您在终端中输入的行时删除引号是 shell 工作方式的一部分。您键入的命令是相同的。研究shell的工作原理,重新研究shell引用的基本介绍。
喜欢这里:
然后“像这里”传递它。您的命令中显然缺少 '
引号,但它们存在于“like here”代码段中。
$ ./sc.sh gcc -c main.c -o out
完全一样
$ ./sc.sh gcc -c "main.c" -o out
完全一样
$ ./sc.sh 'g''c''c' "-""c" 'main.c' '''''-o' 'ou't
它的工作方式与以下相同,只是因为您的 IFS
以及您使用 ="$@"
的方式。研究 $@
的作用并研究 IFS
:
$ ./sc.sh 'gcc -c main.c -o out'
但是下面的命令不同——单引号内的双引号被保留了。
$ ./sc.sh 'gcc -c "main.c" -o out'
作为后续,研究分词。请记住使用 https://shellcheck.net
检查您的脚本