Unable to redirect bash output to variable file name

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
3
down vote

favorite












I am trying to redirect the bash output to a variable file name. Here is my script looks like



#!/bin/bash
for i in `cat servers`
do
if [ "$i" = "198.162.1.3" ];
then
var="apple"
fi
ssh test@$i "uname -n"
done > /tempout/uname_$var.txt


I am getting the filename as /tempout/uname_.txt



Expected filename should be uname_apple.txt







share|improve this question






















  • Don't read lines with for
    – glenn jackman
    Sep 7 at 12:47










  • @glennjackman What makes you think "servers" is a file of lines/records and not just whitespace separated IP addresses?
    – ColleenV
    Sep 7 at 13:54











  • Even if it is, the for i in $(cat file) is wrong. The shell will not only do word splitting (which is the desired effect), it also does filename expansion. set -f is missing.
    – glenn jackman
    Sep 7 at 14:27














up vote
3
down vote

favorite












I am trying to redirect the bash output to a variable file name. Here is my script looks like



#!/bin/bash
for i in `cat servers`
do
if [ "$i" = "198.162.1.3" ];
then
var="apple"
fi
ssh test@$i "uname -n"
done > /tempout/uname_$var.txt


I am getting the filename as /tempout/uname_.txt



Expected filename should be uname_apple.txt







share|improve this question






















  • Don't read lines with for
    – glenn jackman
    Sep 7 at 12:47










  • @glennjackman What makes you think "servers" is a file of lines/records and not just whitespace separated IP addresses?
    – ColleenV
    Sep 7 at 13:54











  • Even if it is, the for i in $(cat file) is wrong. The shell will not only do word splitting (which is the desired effect), it also does filename expansion. set -f is missing.
    – glenn jackman
    Sep 7 at 14:27












up vote
3
down vote

favorite









up vote
3
down vote

favorite











I am trying to redirect the bash output to a variable file name. Here is my script looks like



#!/bin/bash
for i in `cat servers`
do
if [ "$i" = "198.162.1.3" ];
then
var="apple"
fi
ssh test@$i "uname -n"
done > /tempout/uname_$var.txt


I am getting the filename as /tempout/uname_.txt



Expected filename should be uname_apple.txt







share|improve this question














I am trying to redirect the bash output to a variable file name. Here is my script looks like



#!/bin/bash
for i in `cat servers`
do
if [ "$i" = "198.162.1.3" ];
then
var="apple"
fi
ssh test@$i "uname -n"
done > /tempout/uname_$var.txt


I am getting the filename as /tempout/uname_.txt



Expected filename should be uname_apple.txt









share|improve this question













share|improve this question




share|improve this question








edited Sep 7 at 9:44









Rui F Ribeiro

36.2k1271115




36.2k1271115










asked Sep 7 at 9:28









xrkr

5814




5814











  • Don't read lines with for
    – glenn jackman
    Sep 7 at 12:47










  • @glennjackman What makes you think "servers" is a file of lines/records and not just whitespace separated IP addresses?
    – ColleenV
    Sep 7 at 13:54











  • Even if it is, the for i in $(cat file) is wrong. The shell will not only do word splitting (which is the desired effect), it also does filename expansion. set -f is missing.
    – glenn jackman
    Sep 7 at 14:27
















  • Don't read lines with for
    – glenn jackman
    Sep 7 at 12:47










  • @glennjackman What makes you think "servers" is a file of lines/records and not just whitespace separated IP addresses?
    – ColleenV
    Sep 7 at 13:54











  • Even if it is, the for i in $(cat file) is wrong. The shell will not only do word splitting (which is the desired effect), it also does filename expansion. set -f is missing.
    – glenn jackman
    Sep 7 at 14:27















Don't read lines with for
– glenn jackman
Sep 7 at 12:47




Don't read lines with for
– glenn jackman
Sep 7 at 12:47












@glennjackman What makes you think "servers" is a file of lines/records and not just whitespace separated IP addresses?
– ColleenV
Sep 7 at 13:54





@glennjackman What makes you think "servers" is a file of lines/records and not just whitespace separated IP addresses?
– ColleenV
Sep 7 at 13:54













Even if it is, the for i in $(cat file) is wrong. The shell will not only do word splitting (which is the desired effect), it also does filename expansion. set -f is missing.
– glenn jackman
Sep 7 at 14:27




Even if it is, the for i in $(cat file) is wrong. The shell will not only do word splitting (which is the desired effect), it also does filename expansion. set -f is missing.
– glenn jackman
Sep 7 at 14:27










1 Answer
1






active

oldest

votes

















up vote
7
down vote



accepted










The var variable in your code is used before the loop starts to create the output file.



If you want to output the result of the ssh command to a file whose name you construct from $var, then do this:



#!/bin/bash

while read -r server; do
if [ "$server" = "198.162.1.3" ]; then
var='apple'
else
var='unknown'
done

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers


Here, I've also changed the loop so that it reads the input file line by line (ignoring leading and trailing whitespace on each line), and I've made var get the value unknown if the if statement does not take the "true" branch.



Also, you need -n for ssh. Otherwise, ssh would consume all the available input (here redirected from the servers file).



Another change that could be made is to use case ... esac rather than an if statement, especially if the number of IP addresses that you test for is more than a couple:



#!/bin/bash

while read -r server; do
case $server in
198.162.1.3) var=apple ;;
198.162.1.5) var=cottage ;;
198.162.1.7) var=bumblebee ;;
*) var=unknown
esac

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers





share|improve this answer






















  • Thanks it worked :)
    – xrkr
    Sep 7 at 10:09






  • 1




    the input redirection to read is more elegant, but the loop behaves fundamentally different like that. if IP appears in a line together with other words it won't be recognized.
    – Sam
    Sep 7 at 10:12










  • @Sam Yes, the new code expects servers to be a list of IP addresses, one per line.
    – Kusalananda
    Sep 7 at 10:32










  • one per line, with leading and trailing spaces or tabs removed (assuming the default value of $IFS)
    – Stéphane Chazelas
    Sep 7 at 11:07










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f467491%2funable-to-redirect-bash-output-to-variable-file-name%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
7
down vote



accepted










The var variable in your code is used before the loop starts to create the output file.



If you want to output the result of the ssh command to a file whose name you construct from $var, then do this:



#!/bin/bash

while read -r server; do
if [ "$server" = "198.162.1.3" ]; then
var='apple'
else
var='unknown'
done

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers


Here, I've also changed the loop so that it reads the input file line by line (ignoring leading and trailing whitespace on each line), and I've made var get the value unknown if the if statement does not take the "true" branch.



Also, you need -n for ssh. Otherwise, ssh would consume all the available input (here redirected from the servers file).



Another change that could be made is to use case ... esac rather than an if statement, especially if the number of IP addresses that you test for is more than a couple:



#!/bin/bash

while read -r server; do
case $server in
198.162.1.3) var=apple ;;
198.162.1.5) var=cottage ;;
198.162.1.7) var=bumblebee ;;
*) var=unknown
esac

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers





share|improve this answer






















  • Thanks it worked :)
    – xrkr
    Sep 7 at 10:09






  • 1




    the input redirection to read is more elegant, but the loop behaves fundamentally different like that. if IP appears in a line together with other words it won't be recognized.
    – Sam
    Sep 7 at 10:12










  • @Sam Yes, the new code expects servers to be a list of IP addresses, one per line.
    – Kusalananda
    Sep 7 at 10:32










  • one per line, with leading and trailing spaces or tabs removed (assuming the default value of $IFS)
    – Stéphane Chazelas
    Sep 7 at 11:07














up vote
7
down vote



accepted










The var variable in your code is used before the loop starts to create the output file.



If you want to output the result of the ssh command to a file whose name you construct from $var, then do this:



#!/bin/bash

while read -r server; do
if [ "$server" = "198.162.1.3" ]; then
var='apple'
else
var='unknown'
done

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers


Here, I've also changed the loop so that it reads the input file line by line (ignoring leading and trailing whitespace on each line), and I've made var get the value unknown if the if statement does not take the "true" branch.



Also, you need -n for ssh. Otherwise, ssh would consume all the available input (here redirected from the servers file).



Another change that could be made is to use case ... esac rather than an if statement, especially if the number of IP addresses that you test for is more than a couple:



#!/bin/bash

while read -r server; do
case $server in
198.162.1.3) var=apple ;;
198.162.1.5) var=cottage ;;
198.162.1.7) var=bumblebee ;;
*) var=unknown
esac

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers





share|improve this answer






















  • Thanks it worked :)
    – xrkr
    Sep 7 at 10:09






  • 1




    the input redirection to read is more elegant, but the loop behaves fundamentally different like that. if IP appears in a line together with other words it won't be recognized.
    – Sam
    Sep 7 at 10:12










  • @Sam Yes, the new code expects servers to be a list of IP addresses, one per line.
    – Kusalananda
    Sep 7 at 10:32










  • one per line, with leading and trailing spaces or tabs removed (assuming the default value of $IFS)
    – Stéphane Chazelas
    Sep 7 at 11:07












up vote
7
down vote



accepted







up vote
7
down vote



accepted






The var variable in your code is used before the loop starts to create the output file.



If you want to output the result of the ssh command to a file whose name you construct from $var, then do this:



#!/bin/bash

while read -r server; do
if [ "$server" = "198.162.1.3" ]; then
var='apple'
else
var='unknown'
done

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers


Here, I've also changed the loop so that it reads the input file line by line (ignoring leading and trailing whitespace on each line), and I've made var get the value unknown if the if statement does not take the "true" branch.



Also, you need -n for ssh. Otherwise, ssh would consume all the available input (here redirected from the servers file).



Another change that could be made is to use case ... esac rather than an if statement, especially if the number of IP addresses that you test for is more than a couple:



#!/bin/bash

while read -r server; do
case $server in
198.162.1.3) var=apple ;;
198.162.1.5) var=cottage ;;
198.162.1.7) var=bumblebee ;;
*) var=unknown
esac

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers





share|improve this answer














The var variable in your code is used before the loop starts to create the output file.



If you want to output the result of the ssh command to a file whose name you construct from $var, then do this:



#!/bin/bash

while read -r server; do
if [ "$server" = "198.162.1.3" ]; then
var='apple'
else
var='unknown'
done

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers


Here, I've also changed the loop so that it reads the input file line by line (ignoring leading and trailing whitespace on each line), and I've made var get the value unknown if the if statement does not take the "true" branch.



Also, you need -n for ssh. Otherwise, ssh would consume all the available input (here redirected from the servers file).



Another change that could be made is to use case ... esac rather than an if statement, especially if the number of IP addresses that you test for is more than a couple:



#!/bin/bash

while read -r server; do
case $server in
198.162.1.3) var=apple ;;
198.162.1.5) var=cottage ;;
198.162.1.7) var=bumblebee ;;
*) var=unknown
esac

ssh -n "test@$server" 'uname -n' >"/tempout/uname_$var.txt"
done <servers






share|improve this answer














share|improve this answer



share|improve this answer








edited Sep 7 at 15:32

























answered Sep 7 at 9:35









Kusalananda

105k14209326




105k14209326











  • Thanks it worked :)
    – xrkr
    Sep 7 at 10:09






  • 1




    the input redirection to read is more elegant, but the loop behaves fundamentally different like that. if IP appears in a line together with other words it won't be recognized.
    – Sam
    Sep 7 at 10:12










  • @Sam Yes, the new code expects servers to be a list of IP addresses, one per line.
    – Kusalananda
    Sep 7 at 10:32










  • one per line, with leading and trailing spaces or tabs removed (assuming the default value of $IFS)
    – Stéphane Chazelas
    Sep 7 at 11:07
















  • Thanks it worked :)
    – xrkr
    Sep 7 at 10:09






  • 1




    the input redirection to read is more elegant, but the loop behaves fundamentally different like that. if IP appears in a line together with other words it won't be recognized.
    – Sam
    Sep 7 at 10:12










  • @Sam Yes, the new code expects servers to be a list of IP addresses, one per line.
    – Kusalananda
    Sep 7 at 10:32










  • one per line, with leading and trailing spaces or tabs removed (assuming the default value of $IFS)
    – Stéphane Chazelas
    Sep 7 at 11:07















Thanks it worked :)
– xrkr
Sep 7 at 10:09




Thanks it worked :)
– xrkr
Sep 7 at 10:09




1




1




the input redirection to read is more elegant, but the loop behaves fundamentally different like that. if IP appears in a line together with other words it won't be recognized.
– Sam
Sep 7 at 10:12




the input redirection to read is more elegant, but the loop behaves fundamentally different like that. if IP appears in a line together with other words it won't be recognized.
– Sam
Sep 7 at 10:12












@Sam Yes, the new code expects servers to be a list of IP addresses, one per line.
– Kusalananda
Sep 7 at 10:32




@Sam Yes, the new code expects servers to be a list of IP addresses, one per line.
– Kusalananda
Sep 7 at 10:32












one per line, with leading and trailing spaces or tabs removed (assuming the default value of $IFS)
– Stéphane Chazelas
Sep 7 at 11:07




one per line, with leading and trailing spaces or tabs removed (assuming the default value of $IFS)
– Stéphane Chazelas
Sep 7 at 11:07

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f467491%2funable-to-redirect-bash-output-to-variable-file-name%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

What does second last employer means? [closed]

List of Gilmore Girls characters

Confectionery