我尝试在 Bash 脚本中使用 grep 并将结果分配给变量:
RESUlT=$(grep -R -I --exclude-dir=addons "^[^#]*print(" )
但它又回来了
bash: Map/Places/place.gd:: No such file or directory
我在我的终端上测试了它
grep -R -I --exclude-dir=addons "^[^#]*print("
返回我期望的结果,但是
$(grep -R -I --exclude-dir=addons "^[^#]*print(" )
返回错误。
我不知道为什么会发生这种情况。
我的整个脚本:
#!/bin/bash
CYAN='\033[0;36m'
RED='\033[0;31m'
NC='\033[0m' # No Color
RESUlT=$(grep -R -I --exclude-dir=addons "^[^#]*print(" )
echo "${RESULT}"
echo -e "${CYAN}I ${RED}love${NC} Stack Overflow"
bash 的作用:
**bash -o xtrace .check_code.sh**
+ CYAN='\033[0;36m'
+ RED='\033[0;31m'
+ NC='\033[0m'
++ grep -R -I --exclude-dir=addons '^[^#]*print('
+ RESUlT='Map/Places/place.gd: print("enter")'
+ echo ''
+ echo -e '\033[0;36mI \033[0;31mlove\033[0m Stack Overflow'
I love Stack Overflow
终端中有一个奇怪的事情:
whereis grep
返回
grep: /usr/bin/grep /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz
但:
$(whereis /usr/bin/grep)
返回
Command 'grep:' not found, did you mean:
command 'grep' from deb grep (3.11-2)
Try: sudo apt install <deb name>
没有什么奇怪的,只是命令替换有效。
当你测试命令时
shell 首先在命令行上执行命令替换,然后在用命令替换转换命令行后才真正尝试执行它。
从您的
bash -o xtrace ...
输出中,我可以看到执行括号内的命令会产生输出:换句话说,在名为 的文件中
grep
发现一个未注释的字符串,作为包含 的行的一部分 。print(
Map/Places/place.gd
print("enter")
然后,的输出 输出将插入到原始命令行中的...命令替换表达式
grep
的位置。由于整个命令行都包含在...中,因此整个命令行将替换为上面的输出。$(
)
$(
)
然后,shell 尝试执行转换后的命令行。由于原始命令行中只有命令替换表达式,因此 shell 最终尝试将命令替换表达式中的命令输出作为实际命令来执行。
换句话说,它将尝试找到一个具有当前目录相对路径名的可执行文件
Map/Places/place.gd:
并将其print("enter")
作为第一个参数。您可能没有命名任何文件
place.gd:
(文件名中包含冒号)。由于不存在该文件,因此 shell 会显示一条错误消息。实际上,它显示:“我是
bash
,我对您刚才告诉我执行的 有疑问Map/Places/Place.gd:
:有No such file or directory
。”它只是以稍微简洁的形式显示这一点:
在您的脚本中,查看以下两行:
$(
...命令替换表达式中的命令输出)
存储在 shell 变量中RESUlT
。然后,在下一行中,您告诉 shell 输出另一个变量的内容。是的,它们是不同的:请注意第一个变量名中的RESULT
小写字母。l
“终端中的一个奇怪的事情”与您第一次终端测试中的错误完全一样。
第一个命令行
返回输出:
第二行命令行
将首先运行与第一个命令行相同的命令,捕获其输出,用输出替换命令替换表达式,然后尝试执行生成的命令行。
由于命令行现已转换为
shell 现在尝试查找命令
grep:
(带冒号)。由于“命令”中没有斜杠,因此$PATH
会搜索列出的目录,然后显然可选command-not-found
包中的辅助函数会启动。它会产生更详细的错误消息,并给出一些建议,指出
grep:
可能grep
附加了错误的冒号,如果这不是您要查找的命令,则可能需要安装包含所需命令的软件包。但在这种情况下,这些建议不适用,因为您实际上是在盲目地尝试执行另一个命令的输出。