0

script01.sh works just fine

#!/bin/sh -x
egrep 'snmp.* version [123]|ip route ' $1

output

[user@linux ~]$ script01.sh file.txt
+ egrep 'snmp.* version [123]|ip route ' file.txt

However, when I changed the content and put it in variable, it's break.

script02.sh

#!/bin/sh -x
var='snmp.* version [123]|ip route '
egrep $var $1

output script02.sh

[user@linux ~]$ script02.sh file.txt
' x='snmp.* version [123]|ip route
+ egrep 'snmp.*' version '[123]|ip' route $'\r' file.txt
egrep: version: No such file or directory
egrep: [123]|ip: No such file or directory
egrep: route: No such file or directory
: No such file or directory

When I double quoted both $var & $1, this is happen.

script03

#!/bin/sh -x
var='snmp.* version [123]|ip route '
egrep "$var" "$1"

output script03

[user@linux ~]$ script03.sh file.txt
' var='snmp.* version [123]|ip route
' file.txt

1 Answers1

1

Your script breaks because you are using $var unquoted on the command line with egrep. This causes the shell to split it into separate words on spaces, tabs and newlines (by default), and each word is also undergoing filename globbing (e.g. snmp.* would be expanded to all matching filenames in the current directory) before egrep is called with the generated words.

Since egrep would only recognise the first non-option argument as a pattern, the remaining arguments are assumed to be filenames.

Instead, do

#!/bin/sh -x
pattern='snmp.* version [123]|ip route '
grep -E -n --color=auto -e "$pattern" "$1"

grep -E is the same as egrep and since we put the pattern to match in a variable, I'd like to explicitly tell grep that one of the arguments is the pattern with -e. Apart from that, I'm double quoting all variable expansions to avoid the above mentioned word splitting and globbing that the shell would otherwise do on the variables' values (note that $1 would also be affected by this).

Your script also appears to have at least some lines ending with \r (carriage return), as if they were DOS text lines. This could happen if you are writing your script with a Windows text editor. To convert your script to a Unix text file, use dos2unix on the script file.

See also


With a small modification, you script could be made to work on multiple files given on the command line:

#!/bin/sh -x

pattern='snmp.* version [123]|ip route '

for pathname do
    grep -E -n --color=auto -e "$pattern" "$pathname"
done
Kusalananda
  • 333,661
  • Thanks @Kusalananda, I did double quoted it as script03.sh (updated, see above) but it didn't work. – user11392987 Jan 21 '20 at 09:45
  • 2
    @user11392987 I was just about to add that your script may well be a DOS text file. This may happen if you wrote the script on a Windows machine. You may want to convert it to a Unix text file using the dos2unix utility. – Kusalananda Jan 21 '20 at 09:46
  • Thnaks @Kusalananda, yeah that was the root cause. It works after I convert it with dos2unix – user11392987 Jan 21 '20 at 09:49