Reputation: 7526
I have a variable in bash, which is something like
filenames='file 1
file 2
file 3'
I need to send each line in the above variable's content as a single argument to a program. But I can't get bash to that. Here's what I tried:
python -c 'import sys; print sys.argv' $filenames
['-c', 'file', '1', 'file', '2', 'file', '3']
or
python -c 'import sys; print sys.argv' "$filenames"
['-c', 'file 1\nfile 2\nfile 3']
What I'm expecting is something like this
['-c', 'file 1', 'file 2', 'file 3']
I've tried fiddling with the IFS
setting too, but couldn't get it right. Any ideas on this?
Upvotes: 1
Views: 345
Reputation: 530
What about xargs:
$ seq 10 | xargs python -c 'print __import__("sys").argv'
['-c', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
Upvotes: 0
Reputation: 189397
Just to add another option,
OLDIFS=$IFS
IFS='
'
set -- $filenames
python -c 'import sys; print sys.argv; print sys.stdin.readlines()' "$@"
IFS=$OLDIFS
Edit: Add code to save old value in OLDIFS
and restore it afterwards. IFS='whatever' set -- $var
on a single line does not work.
Upvotes: 1
Reputation: 1865
Yet another option:
while read line ; do
python -c 'import sys; print sys.argv' $line;
done <(echo $filenames)
Upvotes: 0
Reputation: 125798
Double-evaluating a command with either eval
or sh -c
can lead to weird bugs if you don't get the extra level of quoting just right. I'd recommend using an array instead, either just by storing the file list as an array to begin with:
filearray=("file 1" "file 2" "file 3")
python -c 'import sys; print sys.argv' "${filearray[@]}"
or by converting it from newline-delimited string to an array:
filenames='file 1
file 2
file 3'
oldIFS="$IFS"; IFS=$'\n'
filearray=($filenames)
IFS="$oldIFS"
python -c 'import sys; print sys.argv' "${filearray[@]}"
Upvotes: 2
Reputation: 1777
$ export filenames="file 1
file 2
file 3"
$ echo "$filenames" | xargs -d\\n python -c 'import sys; print sys.argv'
['-c', 'file 1', 'file 2', 'file 3']
Another way using read
instead of xargs
:
#!/bin/bash
filenames="file 1
file 2
file 3"
cmd="python -c 'import sys; print sys.argv; print sys.stdin.readlines()'"
while read file
do
args="$args \"$file\""
done < <(echo "$filenames")
echo $cmd $args
echo `echo hi | sh -c "$cmd $args"`
Output:
$ ./test.sh
python -c 'import sys; print sys.argv; print sys.stdin.readlines()' "file 1" "file 2" "file 3"
['-c', 'file 1', 'file 2', 'file 3'] ['hi\n']
Upvotes: 2