Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 31 Jan 2017 18:51:03 +0100
From:      Polytropon <freebsd@edvax.de>
To:        byrnejb@harte-lyne.ca
Cc:        "James B. Byrne via freebsd-questions" <freebsd-questions@freebsd.org>
Subject:   Re: Variable assignment in sh
Message-ID:  <20170131185103.7f911dfb.freebsd@edvax.de>
In-Reply-To: <b553c644fccc211f9658b31cfe65e8a0.squirrel@webmail.harte-lyne.ca>
References:  <b831bd9e40321e59910ea8913c7a6302.squirrel@webmail.harte-lyne.ca> <20170131161824.a9f1ef46.freebsd@edvax.de> <b553c644fccc211f9658b31cfe65e8a0.squirrel@webmail.harte-lyne.ca>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 31 Jan 2017 12:11:49 -0500, James B. Byrne via freebsd-questions wrote:
> 
> On Tue, January 31, 2017 10:18, Polytropon wrote:
> > On Tue, 31 Jan 2017 10:06:37 -0500, James B. Byrne via
> > freebsd-questions wrote:
> >> Why am I getting this result when I attempt a simple variable
> >> assignment in the default sh?
> >>
> >> # ENV=$HOME/.shrc; export ENV
> >> ENV=/root/.shrc: Command not found.
> >> export: Command not found.
> >>
> >> This example is taken verbatim from the sh manpage provided with
> >> FreeBSD.
> >
> > This looks like you're running a sh command inside csh.
> > Note that the C shell (FreeBSD's default interactive shell)
> > does variable assignments differently:
> >
> > 	setenv ENV /root/.shrc
> >
> > 	set FOO = 1
> >
> > See "man csh" for details.
> >
> > The command you've presented looks like it would belong into
> > a shell script (FreeBSD's default scripting shell)...
> >
> 
> I note that root is configured in FreeBSD with a default shell of
> /bin/csh and that the user toor has no default shell specified at all
> notwithstanding having a Real Name of 'Bourne-again Superuser'.  I
> checked several of our FreeBSD hosts and all have the same
> configuration for root and toor so I infer that this is how FreeBSD is
> shipped.

That is correct. The user toor has no shell assigned per
default ("inactive user"), and root, as well as all other
users, default to the C shell as the login shell (which
typically is an interactive shell). The real names for
the users can be set according to your needs, they have
a more or less "descriptive value". :-)



> My problem was running a status check command from cron.  Having noted
> that it was failing I tried testing the command having logged on to
> the FreeBSD server as root (using ssh with certificates). This is the
> user with which cron is configured to execute this particular command.

You simply ran into the "wrong shell" problem. :-)



> I am somewhat puzzled by your comment:
> 
> > a shell script (FreeBSD's default scripting shell)
> 
> What does this mean exactly?  Is not CSH a shell?  I thought that the
> shell used in cron was the shell of the user associated with the
> crontab file?  What is cron's default shell otherwise?

FreeBSD comes with two shells:

sh (Bourne shell, actually an Almquist shell) is the shell that
is used for scripting. Most shell scripts start with #!/bin/sh,
which refers to that shell.

csh (C shell, actually a tcsh) is the shell for interactive logins
and dialog use. Many users prefer to replace it with something
they add from ports or packages, like zsh or bash. It is possible
to use that shell for scripting as well, but nobody actually does
this because it's quite terrible. :-)

As cron usually executes shell scripts, sh is being used (and
that explains the sh syntax you've mentioned). The system-wide
/etc/crontab defines SHELL and PATH for commands it executes.

If you'd wanted to interactively test something you want to run
via cron, execute "sh" from your csh prompt to run an interactive
session. Keep in mind that sh _can_ be used interactively too,
but it's somewhat limited in features. You can also store the
commands in a file and execute them with "sh testfile.sh", or
make the script executable and then run it, "chmod +x testfile.sh"
and then "./testfile.sh".



> In any case, I now have set the shell in the root crontab file
> explicitly to /usr/local/bin/bash in hopes of avoiding this problem in
> the future.

That _might_ introduce problems in the future when bash is not
available. My suggestion: Use /bin/sh for scripting except you
need to rely on a "bash-ism", a feature that bash can provide,
but sh cannot. However, you can use bash interactively to test
sh commands, there is "backward compatibility" (bash can be seen
as a superset of sh).




-- 
Polytropon
Magdeburg, Germany
Happy FreeBSD user since 4.0
Andra moi ennepe, Mousa, ...



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170131185103.7f911dfb.freebsd>