bash 带有进程替换的 shell 脚本中的语法错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12120598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Syntax error in shell script with process substitution
提问by Milad Naseri
I have this shell script which I use to back up my system. There is a line:
我有这个 shell 脚本,我用它来备份我的系统。有一行:
tar -Pzcpf /backups/backup.tar.gz --directory=/ --exclude=proc --exclude=sys --exclude=dev/pts --exclude=backups --exclude=var/log / 2> >(grep -v 'socket ignored' >&2)
As you can see, I have been trying to filter out the annoying, useless "socket ignored" error by tar, using this blog post.
如您所见,我一直在尝试通过 tar 过滤掉烦人的、无用的“忽略套接字”错误,使用这篇博文。
What I get from shell upon execution is:
我在执行时从 shell 得到的是:
/bin/sysback: line 45: syntax error near unexpected token
>' /bin/sysback: line 45:tar -Pzcpf /backups/backup --directory=/ --exclude=proc --exclude=sys --exclude=dev/pts --exclude=backups --exclude=var/log / 2> >(grep -v 'socket ignored' >&2)'
/bin/sysback:第 45 行:意外标记附近的语法错误
>' /bin/sysback: line 45:tar -Pzcpf /backups/backup --directory=/ --exclude=proc --exclude=sys --exclude=dev/pts --exclude=backups --exclude =var/log / 2> >(grep -v '忽略套接字'>&2)'
回答by Gilles 'SO- stop being evil'
The syntax you've used is a bash extension to the basic shell syntax, so you must take care to run your script with bash. (Ksh also has >(…)process substitution but doesn't support it after a redirection. Zsh would be fine.)
您使用的语法是基本 shell 语法的 bash 扩展,因此您必须小心使用 bash 运行脚本。(Ksh 也有>(…)进程替换,但在重定向后不支持它。Zsh 就可以了。)
Given the error message you're getting, you are running this script in bash, but in its POSIX compatibility mode, not in full bash mode. Take care to invoke your script with an explicit #!/bin/bashline. #!/bin/shwon't do, even if /bin/shis a symbolic link to bash, because bash runs in POSIX mode if it's invoked under the name sh. Always invoke bash by name if you use bash features.
鉴于您收到的错误消息,您正在 bash 中运行此脚本,但在其 POSIX 兼容模式下,而不是在完整的 bash 模式下。注意使用显式#!/bin/bash行调用脚本。#!/bin/sh不会这样做,即使它/bin/sh是到 bash 的符号链接,因为如果在名称下调用 bash,它会在 POSIX 模式下运行sh。如果您使用 bash 功能,请始终按名称调用 bash。
Also take care not to set the environment variable POSIXLY_CORRECTor to pass the --posixoption on the command line if you want to use bash features.
如果您想使用 bash 功能,还要注意不要设置环境变量POSIXLY_CORRECT或--posix在命令行上传递选项。
Alternatively, don't use this bash-specific syntax; use a portable construct such as the one proposed by Stephane Rouberol.
或者,不要使用这种特定于 bash 的语法;使用可移植的结构,例如Stephane Rouberol提出的结构。
回答by Stephane Rouberol
How about:
怎么样:
tar -Pzcpf /backups/backup.tar.gz --directory=/ \
--exclude=proc --exclude=sys --exclude=dev/pts \
--exclude=backups --exclude=var/log 2>&1 | grep -v 'socket ignored'
回答by Alex
I have found that on gentoo also if sh is a link to /bin/bash if you call the script with 'sh "scriptname"' it doesn't run it as a bash script and fail with:
我发现在 gentoo 上,如果 sh 是 /bin/bash 的链接,如果您使用 'sh "scriptname"' 调用脚本,它不会将其作为 bash 脚本运行,并且会失败:
matchmorethan.sh: line 34: syntax error near unexpected token `<'
matchmorethan.sh: line 34: `done < <( cat $matchfile )'
So if you need to use the Process Substitution feature you need to specifically run it with bash. But I didn't find any reference to this.
因此,如果您需要使用进程替换功能,则需要专门使用 bash 运行它。但我没有找到任何对此的参考。
回答by Aravinth C
Actually you don't have to go for such a redirection in std error when GNU tar provides options to ignore the "socket ignored" warning.
实际上,当 GNU tar 提供忽略“忽略套接字”警告的选项时,您不必在 std 错误中进行此类重定向。
tar --warning='no-file-ignored' -Pzcpf /backups/backup.tar.gz --directory=/ --exclude=proc --exclude=sys --exclude=dev/pts --exclude=backups --exclude=var/log / 2> new.err
You could find the original link with more ignore options here

