0

https://www.youtube.com/watch?v=bu3_RzzEiVo

My intention is to experiment with shell scripts in a file. (FreeBSD 10.2)

I create a file named script.sh

cat > script.sh
set dir = `pwd`
echo The date today is `date`
echo The current directory is $dir
[Ctrl-d]

After giving it execution authority, I run the command

sh script.sh

I get

enter image description here

Why the directory is not displayed?

Then I make a change.

   cat > script.sh
    set dir = `pwd`
    echo The date today is `date`
    echo The current directory is `pwd`
    [Ctrl-d]

This time , it works fine. The directory is shown successfully.

enter image description here

I would like to know why ? Could anyone tell me ?

PPJack
  • 95
  • 1
  • 6

1 Answers1

3

The answer from TessellatingHeckler was on the right track.

From the man page for sh(1):

 set [-/+abCEefIimnpTuVvx] [-/+o longname] [-c string] [-- arg ...]
         The set command performs three different functions:

         With no arguments, it lists the values of all shell variables.

         If options are given, either in short form or using the long
         ``-/+o longname'' form, it sets or clears the specified options
         as described in the section called Argument List Processing.

If you want a command for setting environment variables, that command would be setvar, which you'd use as follows:

setvar dir `pwd`

This is, however, uncommon usage. The more common synonym for this would be:

dir=`pwd`

or

dir=$(pwd)

Note that there are no spaces around the equals sign.

Note also that if you choose to use the setvar command, it's a good idea to put your value inside quotes. The following produces an error:

$ mkdir foo\ bar
$ cd foo\ bar
$ setvar dir `pwd`

Instead, you would need:

$ setvar dir "`pwd`"

Or more clearly:

$ dir="$(pwd)"

Note that you may also need to export your variables. The export command is used to mark a variable that should be passed along to sub shells that the running shell spawns. An example should make this more clear:

$ foo="bar"
$ sh -c 'echo $foo'

$ export foo
$ sh -c 'echo $foo'
bar

One other thing I'll add is that it's common and unnecessary to use date as you're doing in your script, since that command is able to produce its own formatted output. Try this:

$ date '+The date today is %+'

For date options, you can man date and man strftime.

Last tip: when using echo, put things in quotes. You'll produce less confusing and more reasonable output. Note:

$ foo="`printf 'a\nb\n'`"
$ echo $foo
a b
$ echo "$foo"
a
b

Hope this helps!

ghoti
  • 45,319
  • 8
  • 65
  • 104
  • `set` *is* used for setting variables in `(t)csh` but not in `sh`/etc. – Etan Reisner Sep 18 '15 at 04:34
  • @EtanReisner, yes, but the OP is asking about shell scripts launched explicitly with the command `sh script.sh`, There's no mention of csh here. – ghoti Sep 18 '15 at 04:37
  • That was added as additional clarification and I believe the default shell on \*BSD *is* csh (though whether `/bin/sh` is `csh` or just the default user shells I'm not sure). – Etan Reisner Sep 18 '15 at 04:40
  • There is indeed a `/bin/tcsh` in FreeBSD which is included in the base system, and `/bin/sh` is a POSIX Bourne-style shell that is is *not* csh. FreeBSD's `/bin/sh` is based on the Almquist shell (ash), with a few additions. As for the "default" shell, that would be `/bin/sh`, though most people switch to tcsh or install bash (which is not included in base due to licensing issues). – ghoti Sep 18 '15 at 04:44