Syntax error in shell script with process substitu

2019-01-06 23:12发布

问题:

I have this shell script which I use to back up my system. There is a line:

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.

What I get from shell upon execution is:

/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)'

回答1:

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.)

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/bash line. #!/bin/sh won't do, even if /bin/sh is 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.

Also take care not to set the environment variable POSIXLY_CORRECT or to pass the --posix option on the command line if you want to use bash features.

Alternatively, don't use this bash-specific syntax; use a portable construct such as the one proposed by Stephane Rouberol.



回答2:

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'


回答3:

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:

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.



回答4:

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.

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