我正在编写一个 bash 脚本,并且碰巧在脚本在while
循环中等待某些输入时更新了代码(将脚本文件保存到磁盘)。在我返回终端并继续之前的脚本调用后,bash 给出了一个关于文件语法的错误:
/home/aularon/bin/script: line 58: unexpected EOF while looking for matching `"'
/home/aularon/bin/script: line 67: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
所以我尝试执行以下操作:
第一:创建一个脚本,self-update.sh
我们称之为:
#!/bin/bash
fname=$(mktemp)
cat $0 | sed 's/BEFORE\./AFTER!./' > $fname
cp $fname $0
rm -f $fname
echo 'String: BEFORE.';
Run Code Online (Sandbox Code Playgroud)
脚本所做的是读取其代码,将单词“BEFORE”更改为“AFTER”,然后使用新代码重新编写自己。
2运行它:
chmod +x self-update.sh
./self-update.sh
Run Code Online (Sandbox Code Playgroud)
第三个奇迹...
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.
Run Code Online (Sandbox Code Playgroud)
现在,我不会猜到在同一次调用中它会输出AFTER!,肯定会在第二次运行,但不会在第一次运行。
所以我的问题是:这是有意的(按设计)吗?还是因为 bash 运行脚本的方式?逐行或逐个命令。这种行为有什么用处吗?有什么例子吗?
编辑:我尝试重新格式化文件以将所有命令放在一行中,现在不起作用:
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f …
Run Code Online (Sandbox Code Playgroud) 所以,我有一个与Bash非常相似的问题:如何从命令的输出中一次读取一行?, 我在做:
while read path; do mplayer $path; done < <(find-me-random-mp3s)
Run Code Online (Sandbox Code Playgroud)
或者
find-me-random-mp3s | while read path; do mplayer $path; done
Run Code Online (Sandbox Code Playgroud)
该命令find-me-random-mp3s
在一个新行上输出每个文件路径。问题在mplayer
运行时开始,它开始消耗find-me-random-mp3s
输出中的行,即应该path
在每次迭代时填充在变量内的行。
我继续这个肮脏的修复:
find-me-random-mp3s | while read path; do cat /dev/null | mplayer $path; done
Run Code Online (Sandbox Code Playgroud)
但我真的不喜欢它,它也阻止了我与 mplayer 的终端交互。
在这种情况下,我可以使用任何替代方法吗?