Reputation: 6371
The content of 'cmds.txt' is as follow:
ssh -o "StrictHostKeyChecking no" [email protected] "/usr/bin/whoami"
ssh -o "StrictHostKeyChecking no" [email protected] "/usr/bin/whoami"
ssh -o "StrictHostKeyChecking no" [email protected] "/usr/bin/whoami"
ssh -o "StrictHostKeyChecking no" [email protected] "/usr/bin/whoami"
ssh -o "StrictHostKeyChecking no" [email protected] "/usr/bin/whoami"
I'm trying to iterate through this file in prompt and execute them respectively. My command is:
export IFS=$'\n'; for i in `cat cmds.txt`; do $i; done
But it complains bash: ssh -o "StrictHostKeyChecking no" [email protected] "/usr/bin/whoami": No such file or directory.
Is there anything I'm missing? Thanks a lot.
Upvotes: 2
Views: 155
Reputation: 22428
Putting commands in variables isn't a good idea, but if you want to do it any way, then you can do this:
while IFS= read -r line; do
${line[*]}
done <cmds.txt
Note: Don't use quotes in variable $line
( "$line"
or "${line[*]}"
). It won't work for this case.
One way to use your existing code while avoiding using eval
might be:
IFS=$'\n'
for i in `cat cmds.txt`; do #use of $(<cmds.txt) is better than `cat cmds.txt`
bash <<EOF
${i[*]}
EOF
done
Note: using cat
and for
to read line from file isn't recommended, use while
loop instead.
Upvotes: 0
Reputation: 189317
Don't put entire commands in variables and don't loop over lines with for
. The simple and straightforward solution is to factor out only those parameters which actually vary.
while read user_host; do
ssh -o "StrictHostKeyChecking no" "$user_host".myhost.cn /usr/bin/whoami
done <<'____HERE'
adamH@K1201
alexB@K1202
adamR@K1203
kevinC@K1204
rajE@K1205
____HERE
Upvotes: 4
Reputation: 780724
Since you've set IFS
to just a newline, when it does word splitting on $i
it only splits it at newlines, the spaces are no longer treated as delimiters. So the entire line is taken as the command name, not a command followed by arguments.
But if you fix that, it still won't work, because quotes are not processed after expanding a variable. You need to use eval
to put it through all the rules of command parsing.
IFS=$'\n'; for i in `cat cmds.txt`; do eval "$i"; done
But instead of using for
and having to set IFS
, you could do:
while read -r i; do eval "$i"; done < cmds.txt
Upvotes: 2
Reputation: 9272
Why don't you just use source
?
source cmds.txt
Or even shorter:
. cmds.txt
Upvotes: 3