2

Got a line of perl that calls a bash wrapper function after it sources .bash_profile

system ('source ~/.bash_profile; osascript -e \'quit app "Chromium"\'');

Although the wrapper function gets called and is executed perfectly fine, I'm getting an error thrown from an unrelated bash function:

/Users/me/.bashrc: line 9: syntax error near unexpected token `<'
/Users/me/.bashrc: line 9: `  done < <(find -L "$1" -type f -not -name *.swp -print0 | LC_COLLATE=C sort -dz)'

This is the problem function in the .bashrc file:

source_dir() {
  while IFS= read -r -d $'\0' file; do
    source_file "$file"
  done < <(find -L "$1" -type f -not -name *.swp -print0 | LC_COLLATE=C sort -dz)
}

This bash function does not throw errors when sourcing it directly, only when loading it through the Perl script. I'm curious to know why.

I'm running bash version 5.0.2.

StevieD
  • 2,329
  • 13
  • 30
  • osacript doesn't matter. It's just a bash wrapper to the system's 'osascript' command. It is getting called and works as intended. – StevieD Mar 28 '19 at 02:25

1 Answers1

6

perl's system uses /bin/sh as the shell (https://perldoc.perl.org/functions/system.html). It won't understand bash-specific syntax such as process substitutions.

You'll want to explicitly invoke bash:

system 'bash', '-c', q{source ~/.bash_profile; osascript -e 'quit app "Chromium"'};

Using the q{} single-quoting mechanism to avoid backslashing.


A bash note: if you invoke it as an interactive shell, it slurps in the bashrc automatically, so you should be able to do:

system 'bash', '-ic', q{osascript -e 'quit app "Chromium"'};

ref: https://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files

glenn jackman
  • 207,528
  • 33
  • 187
  • 305
  • Thanks. And this has uncovered a blind spot of mine. I'm not sure exactly what the difference is between `sh` and `bash`. This helped: https://stackoverflow.com/questions/5725296/difference-between-sh-and-bash – StevieD Mar 28 '19 at 02:32
  • @StevieD But please check `ls -l /bin/sh`; normally `/bin/sh` is merely a link to another shell, and that's most often `bash`. However, I find that invoking `sh` (from a terminal for instance) comes with differences -- perhaps it doesn't run initialization, even though it really runs `bash`. In this case that would be why explicit `bash` (what always should be done of course) solves your problem. – zdim Mar 28 '19 at 02:53
  • On Mac's, `/bin/sh` goes to `Mach-O 64-bit executable x86_64` – StevieD Mar 28 '19 at 02:54
  • I always thought they were the same as well. The link I provided above points out the differences. – StevieD Mar 28 '19 at 02:55
  • @StevieD They aren't the same and the link you found is good and very useful. I meant to say that these days (I think) the `sh` on Linux is really a copy of bash (or dash). Good to see what it is on Mac. – zdim Mar 28 '19 at 02:59
  • 1
    @zdim Invoking bash with `sh` makes it run in [POSIX mode](https://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html). It does read the startup files, though. – Benjamin W. Mar 28 '19 at 03:38
  • @BenjaminW. Well, alright; thanks for clarifying that. I looked through the differences -- it's a bit of a mess I'd say: they're mostly subtle but of consequence (but don't make it behave like `sh` either). Reads to me like a warning: don't do this; surprises live here. – zdim Mar 28 '19 at 05:22