IFS and command substitution

command substitution bash
variable substitution
bash substitution
bash variable substitution array
bash shell expansion
bash command
command substitution bourne shell
bash variable with

I am writing a shell script to read input csv files and run a java program accordingly.

#!/usr/bin/ksh
CSV_FILE=${1}
myScript="/usr/bin/java -version"
while read row
do
     $myScript
     IFS=$"|"
     for column in $row
     do 
        $myScript
     done
done < $CSV_FILE

csv file:

a|b|c

Interestingly, $myScript outside the for loop works but the $myScript inside the for loop says "/usr/bin/java -version: not found [No such file or directory]". I have come to know that it is because I am setting IFS. If I comment IFS, and change the csv file to

a b c

It works ! I imagine the shell using the default IFS to separate the command /usr/bin/java and then apply the -version argument later. Since I changed the IFS, it is taking the entire string as a single command - or that is what I think is happening.

But this is my requirement: I have a csv file with a custom delimiter, and the command has arguments in it, separated by space. How can I do this correctly?

While loop - Linux Shell Scripting Tutorial, space). The -r option to read command disables backslash escaping (e.g., \n, \t). IFS variable is commonly used with read command, parameter expansions and command substitution. From the bash man page: The shell treats each character of IFS as a delimiter, and splits the results of the other expansions into words on these characters.

IFS tells the shell which characters separate "words", that is, the different components of a command. So when you remove the space character from IFS and run foo bar, the script sees a single argument "foo bar" rather than "foo" and "bar".

When setting IFS to split on newlines, why is it necessary to include , What is meant by command substitution explain with the help of an example? I am writing a bash script that loops over the output of a command substitution and then tries to perform another command substitution within the loop body. Here is the code: #!/usr/bin/bash IFS

The simplest soultion is to avoid changing IFS and do the splitting with read -d <delimiter> like this:

#!/usr/bin/ksh
CSV_FILE=${1}
myScript="/usr/bin/java -version"
while read -A -d '|' columns
do
     $myScript
     for column in "${columns[@]}"
     do 
        echo next is "$column"
        $myScript
     done
done < $CSV_FILE

Command substitution - Linux Shell Scripting Tutorial, , display date and time: echo "Today is $(date)" OR. echo "Computer name is $(hostname)" IFS Specifies internal field separators (normally space, tab, and new line) used to separate command words that result from command or parameter substitution and for separating words with the regular built-in command read.

the IFS should be placed behind of "while"

#!/usr/bin/ksh
CSV_FILE=${1}
myScript="/usr/bin/java -version"
while IFS="|" read row
do
 $myScript
 for column in $row
 do 
    $myScript
 done
done < $CSV_FILE

What is the meaning of IFS=$'\n' in bash scripting?, . As man bash says, it. is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is <space><tab><newline> . How to use "mailx" command to do e-mail reading the input file containing email address, where column 1 has name and column 2 containing To e-mail address and column 3 contains cc e-mail address to include with same email. Sample input file, email.txt Below is an sample code where

Bash variables and command substitution, Command substitution allows the output of a command to replace the command The global variable IFS is what Bash uses to split a string of expanded into  IFS isn't directly related to looping, it's related to word splitting. IFS indirectly determines how the output from the command is broken up into pieces that the loop iterates over. When you have an unprotected variable substitution $foo or command substitution $(foo), there are two cases:

Command Substitution (Bash Reference Manual), Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the  The command substitution expands to the output of commands. These commands are executed in a subshell, and their stdout data is what the substitution syntax expands to. All trailing newlines are removed (below is an example for a workaround). In later steps, if not quoted, the results undergo word splitting and pathname expansion.

Shell expansion, To avoid conflicts with parameter expansion, the string "${" is not considered The shell treats each character of $IFS as a delimiter, and splits the results of the​  After the shell performs variable and command substitution, it scans the results for internal field separators (those defined in the IFS shell variable). The shell splits the line into distinct words at each place it finds one or more of these characters separating each distinct word with a single space.

Comments
  • Why are you storing the command in a variable in the first place? See: Bash FAQ #50.
  • @PesaThe Thanks a lot, I am new to shell scripting and that link was helpful.
  • While this is somewhat on the right track, it doesn't work. Since read row is only reading a single variable, setting IFS just for it has no effect on splitting. The row is still split at the beginning of the for loop. See my answer for some ways this can work.