0

I have a script that expects files as arguments, and for each executes a set of instructions. How should I write it to be able to pipe it to find? In the example below, I haven't used find as such. I assume its output has the same structure as printf "%s\n..." (has it not?)

my-script.sh:

# !/bin/bash

help()
{
    echo "help"
    echo
}

while [[ $# -gt 0 ]]
do
    case $1 in
        *)
            echo "$1"
            shift # past argument
            ;;
    esac
done

Fine:

$ cat foo; echo; cat bar
foo  

bar
$ ./my-script.sh foo bar
foo
bar

But then:

$ printf "%s\n%s\n" "./foo" "./bar" | xargs -n 1 ./my-script.sh
./my-script.sh: 9: ./my-script.sh: [[: not found
./my-script.sh: 9: ./my-script.sh: [[: not found
Erwann
  • 605
  • 1
  • 8
  • 18
  • Seek for error in line 14 of actual script – Archemar Feb 18 '22 at 17:21
  • 2
    You show the code for `my-script.sh` but you're piping to `foo.sh`. Can you show the actual code that is failing? You can also checkout [shellcheck](https://shellcheck.net) for help. – doneal24 Feb 18 '22 at 17:22
  • @doneal24 the code is now copy pasted from `cat my-script.sh` – Erwann Feb 18 '22 at 17:29
  • 4
    Your shebang `# !/bin/bash` is broken I think - you may have whitespace *after* `#!` but not *between* the `#` and the `!`. Likely `xargs` is defaulting to `/bin/sh` in this case - which doesn't support the ksh/bash/zsh `[[ ... ]]` extended test construct – steeldriver Feb 18 '22 at 17:44
  • ... whereas when you run it directly from your (bash?) interactive shell, it's likely being executed using bash in spite of the broken shebang. See for example [Which shell interpreter runs a script with no shebang?](https://unix.stackexchange.com/a/373229/65304) – steeldriver Feb 18 '22 at 18:06
  • @steeldriver problem solved. – Erwann Feb 18 '22 at 18:27
  • @Erwann OK I have turned it into an answer – steeldriver Feb 18 '22 at 18:35

1 Answers1

2

Your shebang

# !/bin/bash

is invalid (it just looks like a comment). Whitespace is permitted after the #!, but not between the # and the !.

Because of that, the script run via xargs is being interpreted by /bin/sh - which does not support the [[ ... ]] extended test syntax (originally from ksh).

When you run the script directly from your interactive shell instead of via xargs, it is likely being interpreted by a bash child shell. See Which shell interpreter runs a script with no shebang?

steeldriver
  • 78,509
  • 12
  • 109
  • 152