-1

I need to use some vars in a script where I use tail and head, my script works when I type it in the terminal but when it is in a .sh file I get this error from the head command:

head: option requires an argument -- n
usage: head [-n lines | -c bytes] [file ...]

The error comes from this pipe of my script:

 head -n $LINE

I tried using variables in another script where only declaring it in the terminal worked. A friend of mine told me to do this, it works but I don't understand why.

export LINE=15
Cœur
  • 37,241
  • 25
  • 195
  • 267
DEEGROY
  • 17
  • 2
  • 1
    Hello. I'm not sure I understand what you need exactly or what you're trying to do actually. If your vars are in the same script as the head command, it should works. Or are you setting vars in one script then calling another one with head in it ? By using export, you're making the vars an environment variable so they become available to all. – Andre Gelinas Jul 03 '18 at 12:23
  • You need to `source script_with_vars.sh` – hek2mgl Jul 03 '18 at 12:32
  • [Capitalize the first person singular pronoun](//english.stackexchange.com/q/172); – Tim Diekmann Jul 03 '18 at 12:50
  • Also see [How to use Shellcheck](https://github.com/koalaman/shellcheck), [How to debug a bash script?](https://unix.stackexchange.com/q/155551/56041) (U&L.SE), [How to debug a bash script?](https://stackoverflow.com/q/951336/608639) (SO), [How to debug bash script?](https://askubuntu.com/q/21136) (AskU), [Debugging Bash scripts](http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html), etc. – jww Jul 03 '18 at 13:17

2 Answers2

1

I'm not sure which part you are confused about, but here's what's going on. head -n $LINE is expecting an integer so if $LINE is empty then head -n has no idea how many lines you want. Example:

(pi5 212) $ unset LINE            # make sure $LINE is empty
(pi5 213) $ echo $LINE            # show it is empty

(pi5 214) $ head -n $LINE < /etc/motd        # see what happens if we try this
head: option requires an argument -- 'n'
Try 'head --help' for more information.
(pi5 215) $ echo "head -n $LINE < /etc/motd"     # this is what the shell sees
head -n  < /etc/motd


(pi5 216) $ export LINE=1     # try it again with LINE set to an integer
(pi5 217) $ echo $LINE
1
(pi5 218) $ head -n $LINE < /etc/motd       
#    ___________
(pi5 219) $ echo "head -n $LINE < /etc/motd"  # it worked! display what the shell sees.
head -n 1 < /etc/motd
(pi5 220) $ 

If your question is about why you need to use export ... then that's a function of your shell. Here's an example:

(pi4 594) $ cat /tmp/x.sh
#!/bin/sh
echo "$foo"

(pi4 595) $ echo $foo

(pi4 596) $ /tmp/x.sh

(pi4 597) $ foo="bar"
(pi4 598) $ /tmp/x.sh

(pi4 599) $ export foo="bar"
(pi4 600) $ /tmp/x.sh
bar

It's explained here:

(pi4 601) $ man sh
...
When a simple command other than a builtin or shell function is to be executed,
it is invoked in a separate execution environment that consists of the following.  
Unless otherwise noted, the values are inherited from the shell.
...
    o      shell variables and functions marked for export, along with variables
           exported for the command, passed in the environment
...
export [-fn] [name[=word]] ...
export -p
          The supplied names are marked for automatic export to the environment
          of subsequently executed commands. 
keithpjolley
  • 2,089
  • 1
  • 17
  • 20
1

export LINE=15 makes your shell script work because it makes the variable LINE available to other shells than the one used to create this variable.

Your script, either because it starts a new shell instance on its own (due to the use of #!/bin/sh or any other Unix shebang) or because you run it by explicitely invoking a shell (. myscript.sh, or sh myscipt.sh for example), doesn't use the same shell instance as your console.

This is well explained here at IBM:

A local shell variable is a variable known only to the shell that created it. If you start a new shell, the old shell's variables are unknown to it. If you want the new shells that you open to use the variables from an old shell, export the variables to make them global.

You can use the export command to make local variables global.

(This linked page is AIX-related but this is actually a general statement.)

Shlublu
  • 10,917
  • 4
  • 51
  • 70