5

I am trying to execute a simple script to capture multiple server's details using svmatch on server names input from a file.

#!/bin/sh
while read line; do
svmatch $line
done < ~/svr_input;

The svmatch command works with no problem when executed as a stand along command.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
Manish Singh
  • 51
  • 1
  • 2
  • Is it intentional that you're string-splitting and glob-expanding the lines read from the file, trimming trailing whitespace, and expanding backslash-escape sequences? If you don't want to do all those things, there are some additional changes called for. – Charles Duffy Feb 18 '14 at 02:50
  • To be more explicit: If you don't want to string-split and glob-expand the lines, make it `svmatch "$line"`. If you don't want to expand backslash-escape sequences in the input, make it `read -r`. If you don't want to strip trailing whitespace from the input, make it `while IFS= read`. – Charles Duffy Feb 18 '14 at 03:23

1 Answers1

12

Redirect your inner command's stdin from /dev/null:

svmatch $line </dev/null

Otherwise, svmatch is able to consume stdin (which, of course, is the list of remaining lines).

The other approach is to use a file descriptor other than the default of stdin:

#!/bin/sh
while IFS= read -r line <&3; do
  svmatch "$line"
done 3<svr_input

...if using bash rather than /bin/sh, you have some other options as well; for instance, bash 4.1 or newer can allocate a free file descriptor, rather than requiring a specific FD number to be hardcoded:

#!/bin/bash
while IFS= read -r -u "$fd_num" line; do
  do-something-with "$line"
done {fd_num}<svr_input
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Excellent explanation and solution. I have a similar issue with a command inside the loop that consumed stdin. Your fd_num option fixed my problem (and teached me how to deal with similar problems on the future. – Gonzalo Cao May 03 '19 at 08:30