LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (http://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   shell script read input from file (http://www.linuxquestions.org/questions/linux-newbie-8/shell-script-read-input-from-file-4175412006/)

rmugunthan 06-18-2012 02:02 AM

shell script read input from file
 
Hi,

Someone, could you please tell me the difference between the below commands.

for host in `cat $file`; do
cat $file | while read host ; do

I thought both the commands are doing the same thing. When i used "cat $file | while read host ; do" in my script the loop disconnect automatically. But "for host in `cat $file`; do" working fine for me.

My script for your reference.

file=/opt/linux_host
for host in `cat $file`;
do
echo "$host"
process=`ssh root@$host "ps -ef | grep sop | grep -v grep | wc -l"`
echo "number of process = $process"
done


Regards,
Mugunthan R

pixellany 06-18-2012 02:49 AM

Please use tags for code examples---makes things easier to read....

I think the common way of doing this is (using your script example):
Code:

file=/opt/linux_host
while read host; do
  echo "$host"
  process=`ssh root@$host "ps -ef | grep sop | grep -v grep | wc -l"`
  echo "number of process = $process"
done < $file


Code:

cat $file | while read host ; do
I maybe think this does not work because there are effectively two read commands?

rmugunthan 06-18-2012 03:04 AM

Hi,

I tried, like you mentioned but that also not helps.

in "/opt/linux_host" file i have list of linux server ipaddress. i need check the particular process status in all the servers. So i write the script like above. If i execute the script like you mentioned also, it ended by giving result from only one server.

But if i modify that to "for host in `cat $file`; do", it is working fine for me. I want to know how it is get differs from the while loop.

Regards,
mugunthan R

pixellany 06-18-2012 03:20 AM

What is the format of the file you are reading from?

Here's a test I just did (I created a file called "list"):
Code:

[mherring@(none) play]$ more list
a
b
c
d
[mherring@(none) play]$ while read item; do echo $item; done < list
a
b
c
d
[mherring@(none) play]$ for item in `cat list`; do echo $item; done
a
b
c
d


grail 06-18-2012 03:28 AM

All 3 examples do the same thing but have different issues depending on your requirement and the data:
Code:

for host in `cat $file`; do
This will work ok as long as the data does not contain any whitespace or it will be broken up based on the values stored in IFS
Code:

cat $file | while read host; do
This will work ok unless you require any information to be available outside the loop, eg. if you place a counter in the loop to be incremented for each host and then display the count after the loop
it will still be zero as the pipe creates a subshell and any changes to the counter are lost once the shell closes
Code:

while read host; do <your_stuff>; done<$file
This is potentially the safest of the 3 as it is not affected by either of the above issues

I would also be quoting your variables if there are any unusual characters in them :)

Hope that helps.

rmugunthan 06-18-2012 04:17 AM

Hi,

Thanks for the reply. I have only ipaddress in the "/opt/linux_host" file. I am working with SLES OS.

While executing the below script i get output from the first serer only and the loop disconnecting automatically.

file=/opt/linux_host
while read host; do
echo "$host"
process=`ssh root@$host "ps -ef | grep sop | grep -v grep | wc -l"`
echo "number of process = $process"
done < $file

But when i use the below one, i get the output from all the servers listed in the "/opt/linux_host" file.

file=/opt/linux_host
for host in `cat $file`;
do
echo "$host"
process=`ssh root@$host "ps -ef | grep sop | grep -v grep | wc -l"`
echo "number of process = $process"
done

Regards,
Mugunthan R

pixellany 06-18-2012 04:22 AM

Again, please post an actual sample of the contents of that file

AND--what happens if you delete (or comment out) the line beginning with process? (I re-ran my test using a file with IP addresses and it worked fine)

rmugunthan 06-18-2012 04:50 AM

Sorry, That file contains only ipaddress. I pasted some of them

10.47.37.44
10.47.37.45
10.47.37.46
10.47.37.47
10.47.37.48
10.47.37.49
10.47.37.65
10.47.37.66
10.47.37.67
.
.
.
.

For normal operations it is working fine. like only echo the server ipaddress. But i am using password less authentication to get information from the remote hosts.

Regards,
Mugunthan R

pixellany 06-18-2012 05:27 AM

Lazy way out: Use the format that works.....:)

Otherwise, in the format that does NOT work, I wonder if something is getting into the data stream besides the contents of file? (I'm trying to think of how to test this)

In both cases, do you get the correct number of processes the first time thru the loop?

chrism01 06-18-2012 07:45 PM

Well, you could add
Code:

set -xv
at the top of your prog; that will show you exactly what the parser sees/does.


All times are GMT -5. The time now is 08:18 PM.