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

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Milad Naseri
  • 4,053
  • 1
  • 27
  • 39
  • I think `2> >(` should be `2>(`. – Anders Lindahl Aug 25 '12 at 09:01
  • Didn't give a syntax error after this change, but didn't filter out the output either. – Milad Naseri Aug 25 '12 at 09:03
  • 2
    The >(...) process substitution syntax is a non-standard feature, and your shell apparently doesn't support it. Use a different shell, or perhaps a newer version of bash. – Alan Curry Aug 25 '12 at 09:30
  • I stand corrected, `2> >(` seems to be the way to redirect stderr into a subshell, and running `(echo "FOO";echo "FOO" >&2) 2> >(grep -v FOO >&2)` outputs a single "FOO" with GNU bash 4.2.24. What shell are you using? – Anders Lindahl Aug 25 '12 at 09:32
  • Quite clearly not Bash, or Bash in POSIX mode, probably from `cron`. – tripleee Aug 25 '12 at 11:45
  • I am using bash on Debian, `ps -p $$` produces `24831 pts/0 00:00:00 bash` and `cat /etc/debian_version` says `6.0.5`. – Milad Naseri Aug 25 '12 at 13:09
  • 1
    `cron` will run your scripts using `sh`, which on a Debian system is `dash`, not `bash`. Adding a `!#/bin/bash` to your script may help (but I'm not as familiar with `cron` as I should be, and have no direct experience with Debian). – chepner Aug 25 '12 at 13:49

4 Answers4

26

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.

Community
  • 1
  • 1
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
7

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'
Stephane Rouberol
  • 4,286
  • 19
  • 18
  • 1
    Even though what you are offering here, is a legitimate alternative to the solution, I will be choosing @Gilles solution as the correct answer, since it answers he point posed by the question. Thank you for the very good answer though. – Milad Naseri Aug 28 '12 at 10:15
2

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.

Zioalex
  • 3,441
  • 2
  • 33
  • 30
  • 1
    Using the `sh` name makes bash set the POSIX flag, same as `set -o posix`. Search for "in posix mode" in bash's documentation; it talks about the details quite a lot.. – Charles Duffy Dec 01 '22 at 15:57
  • 1
    Also, referenced from that documentation, http://tiswww.case.edu/~chet/bash/POSIX – Charles Duffy Dec 01 '22 at 15:59
2

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

Aravinth C
  • 43
  • 1
  • 7