LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   bash dash zsh sh and co | crontab | why so complicated (https://www.linuxquestions.org/questions/linux-general-1/bash-dash-zsh-sh-and-co-%7C-crontab-%7C-why-so-complicated-4175627786/)

taumeister 04-16-2018 11:10 AM

bash dash zsh sh and co | crontab | why so complicated
 
Apparently I still don't quite understand what the individual shells are all about. Again and again I have the problem that scripts don't work properly.
As an example my script completed today ( A part of it ):

When I run the script ( my system Deepin linux, Debian ),
sh lockfile.sh
my lockfile is created correctly! but then the program terminates with the error message : 'testlock.sh: 1: exec: 99: not found'.

Ok, it seems to be that sh cannot start exec..?

If I start with
bash lockfile.sh
my lockfile is not created, but no error message appears.

It's different when I do it on Ubuntu
bash testlock.sh' works.
Under CRON, however, it doesn't work there again, and I have to set it up with 'sh .../testlock.sh'

To be honest, I don't understand.
I thought about the shebang, I say exactly in what context I want to do this?

Can you please enlighten me and give me some examples on how to deal with such problems.

thanks in advance



Code:

#!/bin/bash


LOCKFILE="/virtual_machines/**_-holy-lockfile-_**"
LOCKFD=99

_lock()            { flock -$1 $LOCKFD; }
_no_more_locking()  { _lock u; _lock xn && rm -f $LOCKFILE; }
_prepare_locking()  { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }

_prepare_locking

exlock_now()        { _lock xn; }  # obtain an exclusive lock immediately or fail
exlock()            { _lock x; }  # obtain an exclusive lock
shlock()            { _lock s; }  # obtain a shared lock
unlock()            { _lock u; }  # drop a lock

exlock_now || exit 1


MensaWater 04-16-2018 11:22 AM

https://www.linuxquestions.org/quest...-script-36931/

In addition to what that says and in response to you question about shells. Each shell or interpreter has its own characteristics. You should specify the one you want in the interpreter line of your script.

sh by itself is a bit vague as it might be a reference to the original Bourne shell OR to the more recent Posix shell (on UNIX) or a symbolic link to another shell (e.g. on Linux it might be linked to bash or dash depending on your distro and version). Rather than risking it not being what you expect rather than using interpreter line as:
Code:

#!/bin/sh
Use something like the following to explicitly set which shell you want:
Code:

#!/bin/bash

taumeister 04-16-2018 12:26 PM

Hi,

I read both your link and your answer, but to be honest, it doesn't help me a lot.

I had already written that I knew I was giving the'Shell' with the'Shebang'.
Still, it doesn't explain the difference in behavior.

At last I just want the script to run, I don't know how to make sure it does.
Could you explain to me how I notice in an environment X, how I call a script correctly?
The link says THAT you have to call it up correctly, but not HOW, as so many articles before.

Additionally, it seems, for example, that certain common script commands can be executed in the'Bash', but not when I do this via 'sh'. Which is how you say just a shortcut to'dash' or something similar.
Is there any literature in which I can read, for example, :
If I am in an environment X, then the call must be ' command X' and 'command Y' under Crontab or initab.
How do I know which commands work under'bash' and which don't?

taumeister 04-16-2018 02:28 PM

EDIT:

Thank God! Finally I found an appropriate explanation for the problem with the crontab.
Environment variables!
If I add 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' to the beginning of the crontab, the script works.
This website is really cool.
https://www.digitalocean.com/communi...g-my-sh-script

do you agree with

#!/usr/bin/env bash over
#!/bin/bash ?

MensaWater 04-16-2018 03:12 PM

Interesting that you say my link didn't help when it highlights PATH as a common issue and you later say adding PATH solved your issue.

You seem to be under the misunderstanding that the PATH will always have the same value. It won't - you have to figure out which directories contain the executables you want and insure those directories are in the PATH. You can blindly add directories and in some cases that may find what you need or you can spend time understanding what YOUR script needs and tailor its environment.

taumeister 04-16-2018 03:57 PM

ähm yes. sorry you were right. I got one side mixed up with the other.


In the end, I used the trick of 'cron' to display my own 'environment'

* * * * * * env > /tm/env.output

and adapted it to my needs just like you said.

thanks for your help!

chrism01 04-19-2018 12:38 AM

Also, if you want to (& you should) use a specific shell eg 'bash', just put that in the first line of the file (ie shebang as you do) but DON'T the preface the call with 'sh' eg 'sh myfile.sh' ; just use '/path/to/myfile.sh'.

pan64 04-19-2018 02:13 AM

probably you missed: when you execute a script like: bash lockfile.sh the shebang will be ignored, the script will be executed by bash, what you specified. Similarly: <shell> <script> will always use <shell> to run <script>. shell can be python/perl/whatever/anything which can run text files.
Shebang will be taken into account if you execute the script directly, without specifying the interpreter to use.

From the other hand different shells [may] have different syntax. I suggest you to try shellcheck to validate your script.
Quote:

Ok, it seems to be that sh cannot start exec..?
is definitely a wrong statement, it is just an (syntactically?) incorrect script.
Quote:

do you agree with

#!/usr/bin/env bash over
#!/bin/bash ?
env should only be used if you have no idea about the location of the interpreter you want to use. Otherwise it is just an unnecessary overhead.

hazel 04-19-2018 02:20 AM

In Linux, sh is invariably a link to another program. Traditionally this program is bash, but Debian and all its derivatives (Ubuntu, Mint, etc) use dash. You can find out what sh points to on your system by typing readlink /bin/sh.

Because of these variations it's usually a bad idea to use sh to run your own scripts. Use the actual shell name instead and make sure you are using the correct syntax for that shell. Bash in particular has some extra commands that won't work in dash.

pan64 04-19-2018 02:23 AM

this is not that simple. If I know well bash/dash/... will recognize if they were invoked using sh or bash (or rbash or ...) and will behave accordingly/differently.

jlinkels 04-19-2018 07:29 AM

Quote:

Originally Posted by pan64 (Post 5845026)
this is not that simple. If I know well bash/dash/... will recognize if they were invoked using sh or bash (or rbash or ...) and will behave accordingly/differently.

I am not sure about that. I have been bitten a few times by starting a script with #!/bin/sh which was executed by dash instead of bash. That is about 10 years ago or so and happened after Debian linked sh to dash instead of bash by default. Ever since I use #!/bin/bash. With the complete path name that is.

In cron jobs I also use the complete path name. Even if a path is specified. It might be overkill but often I specify /bin/bash /path/to/my/script so I am sure it runs Bash, no matter what the shebang says.

Furthermore especially to OP: I think it is an extremely bad idea to have "?" or "*" characters in a file name. I know, in some situations Bash can be made to handle "*" in filenames. But why make life harder than it is.

jlinkels

MensaWater 04-19-2018 09:17 AM

Quote:

Originally Posted by jlinkels (Post 5845100)
I think it is an extremely bad idea to have "?" or "*" characters in a file name. I know, in some situations Bash can be made to handle "*" in filenames. But why make life harder than it is.

I agree but don't see where the OP was using either meta-character in a file name.

jlinkels 04-19-2018 10:02 AM

Quote:

Originally Posted by MensaWater
I agree but don't see where the OP was using either meta-character in a file name.

Here:
Quote:

Originally Posted by taumeister (Post 5843821)
Code:

LOCKFILE="/virtual_machines/**_-holy-lockfile-_**"

jlinkels

MensaWater 04-19-2018 10:05 AM

I stand (or rather sit) corrected. :D


All times are GMT -5. The time now is 12:55 PM.