18

Suppose I have in main.sh:

$NAME="a string"
if [ -f $HOME/install.sh ]
    . $HOME/install.sh $NAME
fi

and in install.sh:

echo $1

This is supposed to echo "a string", but it echoes nothing. Why?

  • 2
    Don't update the question please. This way we cannot see what was wrong with your initial question. I just rolled it back. – Valentin Bajrami Dec 24 '14 at 10:07
20

Michael Mrozek covers most of the issues and his fixes will work since you are using Bash.

You may be interested in the fact that the ability to source a script with arguments is a bashism. In sh or dash your main.sh will not echo anything because the arguments to the sourced script are ignored and $1 will refer to the argument to main.sh.

When you source the script in sh, it is as if you just copy and pasted the text of the sourced script into the file from which it was sourced. Consider the following (note, I've made the correction Michael recommended):

$ bash ./test.sh
A String
$ sh ./test.sh

$ sh ./test.sh "HELLO WORLD"
HELLO WORLD
  • "In sh or dash your main.sh will not echo anything because the arguments to the sourced script are ignored and $1 will refer to the argument to main.sh" That's exactly what's happening. Thanks for answering. – Somebody still uses you MS-DOS Dec 20 '10 at 19:59
  • I marked you answer as accepted, because the real issue wasn't with errors in my script, but mainly because I equated sh with bash, and bash does a poor job of emulating sh in this situation. Your answer enlighned me about this issue, thanks; – Somebody still uses you MS-DOS Dec 20 '10 at 20:08
  • 2
    Technically, it's more a kshism here (already there in ksh86, probably earlier). @SomebodystillusesyouMS-DOS, the "sh" specification doesn't say what should happen if you pass extra arguments, so the dash or bash behaviour are not any more "sh" than the other and are equally valid. – Stéphane Chazelas May 4 '18 at 11:08
16

I see three errors:

  1. Your assignment line is wrong:

    $NAME="a string"
    

    When you assign to a variable you don't include the $; it should be:

    NAME="a string"
    
  2. You're missing then; the conditional line should be:

    if [ -f $HOME/install.sh ]; then
    
  3. You're not quoting $NAME, even though it has spaces. The source line should be:

    . $HOME/install.sh "$NAME"
    
  • He also has a few other errors, but I don't think that is necessarily the source of the issue he brings up. – Steven D Dec 20 '10 at 18:55
  • @Steven You're right, there were a couple more I didn't mention; it works for me with the fixes I've listed now – Michael Mrozek Dec 20 '10 at 19:00
  • @Steven When I was throwing together the script to try it I abbreviated it to [ -f $HOME/install.sh ] && . $HOME/install.sh $NAME; I should probably not do things like that when I'm looking for errors – Michael Mrozek Dec 20 '10 at 19:01
  • It looks like the other problem I thought was there actually isn't a problem since he specifically mentions BASH. – Steven D Dec 20 '10 at 19:05
5

simply set your parametrs before sourcing the script !

main.sh

#!/bin/bash
NAME=${*:-"a string"}
if [[ -f install.sh ]];
then
    set -- $NAME ;
    . install.sh ;
fi
exit;

install.sh

#!/bin/bash
echo  " i am sourced by [ ${0##*/} ]";
echo  " with [ $@ ] as parametr(s) ";
exit;

test

u@h$ ./main.sh some args
 i am sourced by [ main.sh ]
 with [ some args ] as parametr(s) 
u@h$
  • How do you set flags? – Jonathan Landrum Sep 27 at 13:40
  • Edit: you apparently just string them after the -- just like they were command arguments: set -- -v foo -l bar -j "${bin}" – Jonathan Landrum Sep 27 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.