6

I have a small sh script that I use to backup to a remote server. It worked on Ubuntu 16.04 for years, but now on 18.04 it fails. At first I thought it was a problem with anacron, but now I think it is a problem with the script itself or with dash. Here is what is happening:

stefan@stefan-Aspire-F5-573T:/etc/cron.daily$ sudo chmod +x rsync-doc-script 
[sudo] Mot de passe de stefan : 
stefan@stefan-Aspire-F5-573T:/etc/cron.daily$ ./rsync-doc-script 
/bin/sh: 0: Can't open *
stefan@stefan-Aspire-F5-573T:/etc/cron.daily$ sh rsync-doc-script
opening connection using: ssh -i /home/stefan/.ssh/id_rsa -l totem MouseHouse rsync --server -vvlogDtprze.iLsfxC . /totembackup/totemdoc  (11 args)
ssh: connect to host mousehouse port 22: Connection refused
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(235) [sender=3.1.2]
stefan@stefan-Aspire-F5-573T:/etc/cron.daily$ 

The error can't open * is preventing the script from running correctly when run by run-parts. Why is this error occurring?

It is not relevant that in the last line, when the script ran, it couldn't establish connection. The server is turned off now.

Here is the script:

#!/bin/sh                                                                                     *
rsync -azvv -e "ssh -i /home/stefan/.ssh/id_rsa" /home/stefan/Documents/ totem@MouseHouse:/totembackup/totemdoc

2 Answers 2

10

I can't tell for sure but it looks like you have a typo on the first line where there's a stray * over to the right.

#!/bin/sh                                                                                     *

^^^ Scroll over to the right to see it.

Example

$ cat script.bash
#!/bin/sh                    *
echo hi

Run directly:

$ ./script.bash
/bin/sh: *: No such file or directory

Run via sh:

$ sh script.bash
hi

General advice

It's generally advisable to use the exact shell you're expecting with your shebang. If you suspect that you're running into problems where you suspect dash or some other shell is being used, you can always make your shebang explicit by changing it from #!/bin/sh as your shebang #!/bin/bash.

The above is based on your comment below:

but now I think it is a problem with the script itself or with dash.

0
5

The error can't open * is preventing the script from running correctly when run by run-parts.  Why is this error occurring?

When you execute a file1 that is not a binary executable, but is a text file with a shebang (the first line of the file begins with #!), the kernel (with no help from any shell) builds a command that is the shebang line (the part after the #!) followed by the original, user-level command line.  For example, if doc-script begins

#!/bin/sh -x

and it is invoked

./doc-script bashful dopey

then the kernel builds and executes the following command:

/bin/sh -x ./doc-script bashful dopey

which causes the shell to read and interpret the doc-script script, with the xtrace (-x) option set, and with $1 = bashful and $2 = dopey.  (Naturally, $0 is ./doc-script.)  If the original user-supplied command is

./doc-script b* ??p* [ghs]*

then the shell that handles that command (for simplicity, let’s assume that that is the interactive shell running on the user’s terminal) might expand this to

./doc-script bashful dopey grumpy happy sleepy sneezy

and so the kernel builds and executes the following command:

/bin/sh -x ./doc-script bashful dopey grumpy happy sleepy sneezy

But remember: the processing of the shebang line is done by the kernel, not by the shell.  Therefore, if the shebang is

#!/bin/sh *

then the final, constructed command is

/bin/sh * ./doc-script bashful dopey grumpy happy sleepy sneezy

because glob expansion doesn’t happen here.  As far as the shell is concerned, this looks like the user typed

/bin/sh '*' ./doc-script bashful dopey grumpy happy sleepy sneezy

and, because * doesn’t begin with -, the shell interprets it as a filename, so it tries to run a script called * with $0 = *$1 = ./doc-script, $2 = bashful, $3 = dopey, etc.  And, since there is no script called *, this fails.
__________
1 I am assuming that the process has the permissions necessary to execute the file.

You must log in to answer this question.

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