Passing an array as argument of a java program in bash

65 Views Asked by At

I am running a Java program through a bash script. My plan is to iterate over a for-loop to create the argument to pass:

lastLine=$(cat $info_file | wc -l)

countID=0

cat $info_file | while read fileID; do

initVar="${initVar} ${fileID}.txt"

countID=$(($countID + 1))

if [ "$countID" == "$lastLine" ]; then
echo $initVar > tmp_${SampleID}.txt
fi

done

InputListVar=$(cat tmp_${SampleID}.txt)

java ProgramX --input "${InputListVar[@]}" --output $output_file

However, when I run the script above I get the following message:

Exception in thread "main" java.lang.IllegalArgumentException: Illegal character in path at index 15 

I suppose that this is due to the space in the list of files I provide within the InputListVar array (as suggested here Illegal character in path at index 16). How could I solve this issue?

2

There are 2 best solutions below

0
markp-fuso On BEST ANSWER

I don't work with java but I'm assuming java wants to see something like:

java --input file1 file2 file3 --output ...

OP's script should generate this format IF InputListVar is defined as an array, but it's not. The following creates a scalar variable:

InputListVar=$(cat tmp_${SampleID}.txt)

If we assume the following contents of the input file:

$ cat tmp_${SampleID}.txt
file1
file2
file3

Then we get the following:

$ InputListVar=$(cat tmp_${SampleID}.txt)
$ typeset -p InputListVar
declare -- InputListVar=$'file1\nfile2\nfile3'

So when this is fed to java the following happens:

java --input "${InputListVar[@]}" --output ...

# becomes

java -- input file1
file2
file3 -- ouput ...

# hence an error

NOTE: ${InputListVar} is technically the same as ${InputListVar[0]} so OP's ${InputListVar[@]} becomes ${InputListVar[0]} which becomes ${InputList}

We can 'fix' the issue by insuring we're working with an array:

InputListVar=( $(cat tmp_${SampleID}.txt) )           # note the additional pair of outer parens

Back to the java call:

java --input "${InputListVar[@]}" --output ...

# becomes

java -- input file1 file2 file3 -- ouput ...
0
pjh On

Assuming you have got Bash 4.0 or later (for readarray) this code may do what you want:

readarray -t fileids <"$info_file"
java ProgramX --input "${fileids[@]/%/.txt}" --output "$output_file"
  • readarray -t fileids <"$info_file" makes each line of "$info_file" an element of the fileids array.
  • "${fileids[@]/%/.txt}" expands to the (quoted) elements of fileids with .txt appended to each of them.