带有进程替换的shell脚本中的语法错误

时间:2012-08-25 08:57:39

标签: linux bash shell process-substitution

我有这个用于备份系统的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)

正如你所看到的,我一直在试图过滤出烦人的,无用的"套接字被忽略" tar的错误,使用this blog post

执行时我从shell获得的是:

  

/ 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' socket忽略'>& 2)'

4 个答案:

答案 0 :(得分:18)

您使用的语法是基本shell语法的bash扩展,因此您必须注意使用bash运行脚本。 (Ksh也有>(…)进程替换但在重定向后不支持它.Zsh没问题。)

鉴于您收到的错误消息,您在bash中运行此脚本,但在其POSIX兼容模式下,而不是在完全bash模式下。注意使用明确的#!/bin/bash行调用脚本。即使#!/bin/sh是bash的符号链接,/bin/sh也不会这样做,因为如果以名称sh调用bash,它将以POSIX模式运行。如果使用bash功能,请始终按名称调用bash。

如果要使用bash功能,请注意不要设置环境变量POSIXLY_CORRECT或在命令行上传递--posix选项。

或者,不要使用这种特定于bash的语法;使用便携式构造,例如Stephane Rouberol提出的构造。

答案 1 :(得分:7)

怎么样:

 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'

答案 2 :(得分:2)

我发现在gentoo上也是如果sh是/ bin / bash的链接,如果用“sh”脚本名称调用脚本“'它不会将它作为bash脚本运行并且失败并且:

matchmorethan.sh: line 34: syntax error near unexpected token `<'
matchmorethan.sh: line 34: `done < <( cat $matchfile )'

因此,如果您需要使用Process Substitution功能,则需要使用bash专门运行它。但我没有找到任何参考。

答案 3 :(得分:1)

实际上,当GNU tar提供忽略&#34;套接字忽略&#34;的选项时,你不必在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