script01.sh works just fine

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


[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.


#!/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.


#!/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 Answer 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"
  • Thanks @Kusalananda, I did double quoted it as script03.sh (updated, see above) but it didn't work. Jan 21, 2020 at 9: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, 2020 at 9:46
  • Thnaks @Kusalananda, yeah that was the root cause. It works after I convert it with dos2unix Jan 21, 2020 at 9:49

You must log in to answer this question.

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