2

Hi I've been trying to figuring out how to simply pass an file.txt with multiple lines into a bash script args to run as a command. Not sure I should be doing while loops?

So the text file just contains something like about.

ip_addr1,foo:bar
ip_addr2,foo2:bar2
user@ip_addr3,foo3:bar3

And I just want a bash script to take the content from that file and use it as a bash script, as an example like

ssh ip_addr1 'echo "foo:bar" > /root/text.txt' 
ssh ip_addr2 'echo "foo2:bar2" > /root/text.txt'
ssh user@ip_addr3 'echo "foo3:bar3" > /root/text.txt'  

So the script will execute depending on how many lines the text file has..

2
  • Can you please clarify what specifically you need help with? Reading a line from a file? Seperating the tokens? Forming the command? etc. Have you made any attempt or have any ideas?
    – kaylum
    Jan 17, 2020 at 3:41
  • Hi, @kaylum I basically tried to use a text file in a bash script, whereas the text file will be imported into linux command that runs in the bash script. The text file contains info that's separated with a comma. I've tried a couple of attempts but no success.
    – Ryan
    Jan 17, 2020 at 4:43

2 Answers 2

2

You can iterate through the lines of the file with the bash read command as suggested from the answers to this question.

while read -r line
do
  # $line will be a variable which contains one line of the input file
done < your_file.txt

You can use read again with the IFS variable to get the content from each line split by the IFS variable, as suggested by answers to this question.

while read -r line
do
  # $line will be a variable which contains one line of the input file
  IFS=, read -r ip_addr data <<< "$line"
  # now, $ip_addr stores the stuff to the left of the comma, and $data stores the stuff to the right
done < your_file.txt

From there, you can run whatever command you want to run with the new variables.

while read -r line
do
  # $line will be a variable which contains one line of the input file
  IFS=, read -r ip_addr data <<< "$line"
  # now, $ip_addr stores the stuff to the left of the comma, and $data stores the stuff to the right
  ssh "$ip_addr" "echo \"${data}\" >  /root/text.txt"
done < your_file.txt

If you don't need the $line variable, you can use a single read command.

while IFS=, read -r ip_addr data
do
  # now, $ip_addr stores the stuff to the left of the comma, and $data stores the stuff to the right
  ssh "$ip_addr" "echo \"${data}\" >  /root/text.txt"
done < your_file.txt
6
  • 1
    See also Understanding "IFS= read -r line" (read line does not read a line).
    – Kusalananda
    Jan 17, 2020 at 7:06
  • Hi there this perfectly works, though how would I made it read on to the next line since it only execute once from the first line?
    – Ryan
    Jan 17, 2020 at 7:12
  • Why do you read each line twice? Couldn't you just use IFS=, read -r ip_addr data from the start?
    – Kusalananda
    Jan 17, 2020 at 7:37
  • Well trying that will only read the first line, it doesn't continue till the ending trail.
    – Ryan
    Jan 17, 2020 at 8:00
  • @Kusalananda you're right, you can just read once. If any further processing needs to be done on the line as a whole, it may be useful to have it as a variable. I'll edit the answer with your suggestion though.
    – rchome
    Jan 18, 2020 at 2:59
0

Transform the input file to a shell script using sed

$ sed -e "s|\([^,]*\),\(.*\)|ssh -n \"\1\" 'echo \"\2\" >/root/text.txt'|" file
ssh -n "ip_addr1" 'echo "foo:bar" >/root/text.txt'
ssh -n "ip_addr2" 'echo "foo2:bar2" >/root/text.txt'
ssh -n "user@ip_addr3" 'echo "foo3:bar3" >/root/text.txt'

or awk,

$ awk -F ',' '{ printf("ssh -n \"%s\" '\''echo \"%s\" >/root/text.txt'\''\n", $1, $2) }' file
ssh -n "ip_addr1" 'echo "foo:bar" >/root/text.txt'
ssh -n "ip_addr2" 'echo "foo2:bar2" >/root/text.txt'
ssh -n "user@ip_addr3" 'echo "foo3:bar3" >/root/text.txt'

Then save the output of either of those to a file using a redirection and run it with sh. This way you additionally have a record of exactly what commands were executed.

Alternatively, you could execute the output of either command with

...either command above... | sh -s
3
  • Hmm given the example with the txt file, I might have more then 50-60 lines of credentials. So wouldn't it be better to have it loop+while?
    – Ryan
    Jan 17, 2020 at 7:15
  • 1
    @Ryan If you want something that is better for running commands on a set of machines, or for distributing data to a cluster, look at Ansible or similar software. Personally, I would create all text.txt files on a central admin server, and then distribute them from there rather than assuming that echo would preserve the strings literally.
    – Kusalananda
    Jan 17, 2020 at 7:19
  • Well the point of the bash script is just to simply execute all the same commands with different credentials, without looking into software where I don't have to spend time playing around with newer repo as an example.
    – Ryan
    Jan 17, 2020 at 7:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .