3

I was trying to develop a simple bash script where one positional parameter is used. But for no reason the parameter is empty. The bash script is given bellow.

#!/bin/bash
ulimit -s hard
if [ "$1" != "" ]; then
    echo "Positional parameter 1 contains something"
else
    echo "Positional parameter 1 is empty"
fi
root="$(dirname "$(readlink -f "$1")")"
dir="$(basename "$(readlink -f "$1")")"
path=$root/$dir
echo $path

While I was running the script file in the following way, it shows empty strings.screenshot of output

I was using bash -c command since i need to run the bash script from a java code using ProcessBuilder Class.

I know very little about bash scripting and I tried in more simpler way like:

root=`dirname $1`
dir=`basename $1`
path=$root/$dir

But the result is all the same.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Unless the file does not exist and `readlink -f` returns nothing. – David C. Rankin Jan 19 '18 at 23:47
  • Not helping. Its shows "dirname: missing operand" – C M Khaled Saifullah Jan 19 '18 at 23:47
  • You can test for empty string with [ -z "$1" ], better bash style. Also, to avoid errors add an 'exit 1' if parameter is empty. – LMC Jan 19 '18 at 23:50
  • 1
    @LuisMuñoz In `bash`, it's also possible to do something like this: `[[ ! $1 ]]`. – PesaThe Jan 19 '18 at 23:53
  • 2
    ...in this case, though, you don't need the `-c` at all. `bash scriptname arg` would solve your problem (as would relying on the executable bit and shebang, and running `/path/to/scriptname arg` with no explicit interpreter). – Charles Duffy Jan 20 '18 at 00:30
  • Why do you think ProcessBuilder requires you to use `bash -c`? You can certainly create a `new ProcessBuilder("/path/to/simcadRunner", "/path/to/bcb_reduced/40")`. – Charles Duffy Jan 20 '18 at 00:32

1 Answers1

4

From the bash documentation:

If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.

The emphasis here is in the original, which is nice since it's a bit surprising, but we can see it with:

bash -c 'echo zero: $0 one: $1 two: $2' a b c

which produces:

zero: a one: b two: c

as output.

In short, you should be inserting an extra argument to take up the $0 position, or adjusting all your argument numbers (I'd go for the former solution).

torek
  • 448,244
  • 59
  • 642
  • 775
  • could not he run bash -c 'script arg' ? – eric.v Jan 19 '18 at 23:53
  • 1
    @eric.v: He could run `bash script arg1 arg2 ...` since the script *is* a file. Then $0 is the file name, and $1 on up are the arguments as usual. I was assuming here that the file was a stand-in for something that will go in as `-c` arguments eventually—if not, it's even better to just make the file a stand-alone executable, by starting it with an appropriate `#!` line. – torek Jan 20 '18 at 00:02
  • 1
    @eric.v, `bash -c 'script arg'` causes problems if you want to get your `arg` from a non-exported variable without creating `eval`-equivalent security holes. Much, *much* safer to keep data out-of-band from code -- why is why `bash -c '...script...' _ arg1 arg2` is the conventional formulation. – Charles Duffy Jan 20 '18 at 00:28
  • Thanks for the clarification guys – eric.v Jan 20 '18 at 09:04