0

I'm trying to get the audio type in an OSX sh script using ffprobe: ffprobe "$i" |& egrep -ci "vorbis|aac" it works from cli in tcsh but not from script. |& doesn't seem to work from inside script. |& redirects the output from ffprobe, otherwise ffprobe prints out to cli. Any help is appreciated.

##mkv files
for i in "$input"*.mkv ; do
    if [ -e "$i" ] ; then
         ##1st check type(vorbis|aac)
         type=$(/usr/local/bin/ffprobe "$i" |& egrep -i "vorbis|aac")
         echo "Test: $type"
         ##just get audio format
         type=$(/usr/bin/perl -e '$_=@ARGV[0];if (/(aac|vorbis)/ig) {print $1;}' "$type")
         echo "Type: $type"
         exit
    fi
done

error I get is:

command substitution: line 46: syntax error near unexpected token `&'
command substitution: line 46: `/usr/local/bin/ffprobe "$i" |& egrep -i "vorbis|aac"'
tripleee
  • 175,061
  • 34
  • 275
  • 318
snjagr
  • 20
  • 5
  • Why do you need `|&` (I don't normally use that so I don't remember what it is). Can't you just do `ffprobe "$i" | grep -i ...` ? Also your code looks like `bash` or related shells, not tcsh. For instance, `tcsh` uses `endif`, not `fi`. Good luck. – shellter Dec 06 '15 at 05:01
  • Why do you think this is a `tcsh` script? This looks like a Bourne shell script. `|&` is not a standard Bourne shell construct, and only works with `bash` and perhaps some other Bourne shell extensions (and `csh` also has it). This script should work fine if you run it with `bash`. – Martin Tournoij Dec 06 '15 at 07:17
  • Perhaps you should clarify your question ([edit] the text, and the tags too!), and include the actual error message; as it is, we have to guess too many things. – tripleee Dec 06 '15 at 07:40
  • @Carpetsmoker I rolled back your tag edit, because [tag:sh] is obviously no more correct than [tag:tcsh] here. Maybe wait for the OP to clarify. – tripleee Dec 06 '15 at 07:45
  • I've always used `fi` to close `if`'s, its always worked so I never questioned it. The `|&` does work with tcsh. I've updated the question with the error. – snjagr Dec 06 '15 at 09:21
  • So how are you running this script? If you add a `ps` command to the script, how is it displayed in the resulting process listing? – tripleee Dec 06 '15 at 09:49
  • @tripleee Okay, but there is not a single `csh` construct in this script except `|&`, which is coincidental as it's shared with `bash`. – Martin Tournoij Dec 06 '15 at 10:18
  • this is run as `sh ./Vid2Audio.sh "folder_path"` in a tcsh environment. its all pretty standard tcsh as far as i know.. the #! is `#! /bin/sh` – snjagr Dec 06 '15 at 10:40
  • So @Carpetsmoker you were right after all. Apologies for not trusting your ability to diagnose the situation here. – tripleee Dec 06 '15 at 12:09
  • Well this has been an amusing learning event. Basically how I think I got here is I have always run a tcsh environment, since learning shell. Then when I learned scripting I apparently learned bash thinking it was tcsh, I've always started my scripts with `#!/bin/sh` and run them using `sh`, so I never noticed anything wrong, the script would run in posix bash and return the output to me in tcsh... in osx `sh` invokes bash in posix mode anyway thanks for helping me clear up a decade old misunderstanding of mine. :) – snjagr Dec 08 '15 at 01:53

1 Answers1

0

You are attempting to use tcsh syntax in a sh script; the fact that this does not work should be unsurprising, although you appear to be unaware that they are two different languages.

Perhaps the most straightforward immediate solution for your script is to run it in bash instead of sh, where the former supports the tcsh syntax you tried to use, not just coincidentally but because it has loaned many good and some less good ideas from tcsh, too, while preserving full backwards compatibility with POSIX sh.

Assuming the information you want is printed to standard output py ffprobe, you could also switch to a regular pipe, and keep the sh shebang line. Either way, explicitly invoking the script with sh is less recommended -- just mark the file as executable and invoke it directly, and the system will use whichever interpreter the shebang specifies (and conversely, the shebang will simply be ignored if you explicitly specify an interpreter).

There is a wide consensus that tcsh should be avoided for both scripting and interactive use -- I would advise you to consider also switching to bash for interactive use, which will unify the syntax you apparently already use for scripts with the syntax for interactive use. In fact, you are currently missing out on one of the attractive features of the shell by using an incompatible interactive shell.

Tom Christiansen's csh.whynot is the canonical reference criticism of the C shell. While tcsh fixes a good number of the bugs and inconsistencies from csh, many do still remain. Switching to one of the dominant shells will also give you a broader network of help, learning, and troubleshooting resources to support you.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • This is almost the right answer, so i might as well mark it. On my version of osx `sh` invokes `bash` in posix mode. so the script was being run from tcsh in bash. I just had to change the `ffprobe` call to a typical bash redirect `type=\`/usr/local/bin/ffprobe "$i" 2>&1 | egrep -i "audio"\`` – snjagr Dec 08 '15 at 02:06
  • The fact that `sh` on your system runs Bash in POSIX mode is coincidental. Scripts marked with `#!/bin/sh` should (or rather, basically must) obey a restricted syntax where many Bash constructs are not available. On many Debian-based distros, the default `sh` was changed to `dash` from previously being a symlink to Bash (like on your system) and this uncovered many cases where they had been careless, and/or where Bash should have been more strict. You want to avoid being bit by that; future versions of Bash just might be tighter in what bashisms they allow in POSIX mode. – tripleee Dec 08 '15 at 05:25
  • If you found this answer helpful, please accept it by clicking the hollow checkmark next to the big score number so it turns solid green. This awards me some reputation points, but more importantly, marks your question so that it no longer comes up as unresolved. – tripleee Dec 08 '15 at 05:27