I was asked the other day to help someone who was running a bash
script where part of the output was command not found.
That’s not an especially unusual error, often stemming from users perhaps not understanding the role of the PATH
environment variable. In this case, though, the user had reduced the script to something very simple that was showing the error:
$ cat test.sh #!/bin/bash if [ 1 -eq 1 ]; then X=$(date) echo $X fi
The Error
Running it:
$ ./test.sh ./test.sh: line 3: command not found
Running it with -x
switch:
$ bash -x test.sh + '[' 1 -eq 1 ']' ++ date + X=Thu 4 May 10:14:37 BST 2017 test.sh: line 3: command not found + echo
Checking that bash
finds the date command shows no problem:
$ which date /bin/date
Even putting the full path of the command in didn’t fix the issue.
The Solution
After a lot of testing and some strange results, I finally dumped the script with od
:
$ od -c test.sh 0000000 # ! / b i n / b a s h \n i f [ 0000020 1 - e q 1 ] ; t h e n 0000040 \n 302 240 302 240 X = $ ( d a t e ) 0000060 \n e c h o $ X \n f i \n 0000100
Aha! Those octal 302 240 codes look odd! They are the Unicode non-breaking space, but bash
doesn’t understand them. Inside vim
, you can highlight non-ASCII characters with:
:set hlsearch /[^\d0-\d127]
That showed the two non-breaking spaces, and makes it easier to remove them.
It turned out that the user had copied and pasted some code from a website, and that was how the Unicode characters became embedded in his script. Once removed, the script worked as intended.
Could this Linux Tip be improved? Let us know in the comments below.