LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   What Is Wrong With This Bash Script File? (https://www.linuxquestions.org/questions/programming-9/what-is-wrong-with-this-bash-script-file-441224/)

George2 05-03-2006 07:53 AM

What Is Wrong With This Bash Script File?
 
Hello everyone,


When I executing the following bash script file,

--------------------
Foo=gcc\ -DDEBUG
Goo=-I.
Zoo=$(Foo) $(Goo)
echo $(Zoo)
--------------------


--------------------
./test.sh: line 1: Goo: command not found
./test.sh: line 1: Foo: command not found
./test.sh: line 1: Zoo: command not found
--------------------

I simply want to set three variables and test their output. Are there anything wrong with this script file?


thanks in advance,
George

taylor_venable 05-03-2006 08:02 AM

Don't put parentheses around the variable substitutions; just do $Foo. But this line should be different:
Code:

Zoo="$Foo $Goo"
You have to quote this line if you want it to work, I think. In fact, you should quote any assignment that isn't a number, even if you don't have to.

muha 05-03-2006 10:49 AM

Or use ${Foo}
Read more over here: http://www.linuxcommand.org/

And don't forget the include the bash-header:
Code:

#!/bin/bash

--- rest of script ---

exit


taylor_venable 05-03-2006 09:06 PM

I'm curious why you say to use exit at the end, instead of just naturally allowing EOF to terminate the script. Can Bash be configured to ignore EOF as a session terminator?

Also, I just want to point out, with respect, that I believe it's more flexible to use "#!/usr/bin/env bash" than "#!/bin/bash", since bash may not be installed into /bin (as it is not on BSD systems, for example). I think env is either stored in or symlinked in /usr/bin on every Unix-like installation.

George2 05-04-2006 01:23 AM

Hi taylor_venable,


Quote:

Originally Posted by taylor_venable
Don't put parentheses around the variable substitutions; just do $Foo. But this line should be different:
Code:

Zoo="$Foo $Goo"
You have to quote this line if you want it to work, I think. In fact, you should quote any assignment that isn't a number, even if you don't have to.

Your method works! I used Makefile style to write bash files, so I add () around variables. I have also found another approach to work out this solution.

Zoo=$Foo\ $Goo


regards,
George

George2 05-04-2006 01:26 AM

Cool muha! Youe method works!


Quote:

Originally Posted by muha
Or use ${Foo}
Read more over here: http://www.linuxcommand.org/

And don't forget the include the bash-header:
Code:

#!/bin/bash

--- rest of script ---

exit


Why should we add exit?


regards,
George

George2 05-04-2006 01:28 AM

Hi taylor_venable,


Quote:

Originally Posted by taylor_venable
I'm curious why you say to use exit at the end, instead of just naturally allowing EOF to terminate the script. Can Bash be configured to ignore EOF as a session terminator?

Also, I just want to point out, with respect, that I believe it's more flexible to use "#!/usr/bin/env bash" than "#!/bin/bash", since bash may not be installed into /bin (as it is not on BSD systems, for example). I think env is either stored in or symlinked in /usr/bin on every Unix-like installation.

What is the function of env? I have never used it before. Is it available on both Linux and UNIX (like Solaris)?


regards,
George

muha 05-04-2006 02:43 AM

@exit: it's something i picked up from over here: http://www.linuxcommand.org/wss0090.php#exit
I thought including exit on the last line of code caused a script to terminate succesfully (so no errors were made).

chrism01 05-04-2006 03:02 AM

The script exits with the result value of the last cmd run. If you want to set it explictly, use
exit <some_positive_integer_or_zero>
conventionally on Unix style systems, zero is success, (positive) int is an error. iirc, negative value is not allowed here.

taylor_venable 05-04-2006 11:06 AM

From the manual page: "The env utility executes another utility after modifying the environment as specified on the command line. ... Probably the most common use of env is to find the correct interpreter for a script, when the interpreter may be in different directories on different systems. The following example will find the `perl' interpreter by searching through the directories specified by PATH."
Code:

#!/usr/bin/env perl
In other words, env applies an environment (the current one, modified by options passed to env) to an executable. So actually, you can use env to specify all kinds of environment variables, including PATH and LD_LIBRARY_PATH, so that things are just right when the script gets executed. This feature would be increasingly useful in varied environments. The env binary is stored in /usr/bin on all three of the major BSDs, and also on Slackware Linux, in my experience. I think it's somewhat of a standard, so it should be there on other systems as well, but you'll have to check to be sure.

George2 05-07-2006 03:52 AM

Cool muha! I have never used it in this way before. I think there must be some default return values if I do not call exit explicitly at the last line of a script. Right?


Quote:

Originally Posted by muha
@exit: it's something i picked up from over here: http://www.linuxcommand.org/wss0090.php#exit
I thought including exit on the last line of code caused a script to terminate succesfully (so no errors were made).


regards,
George

George2 05-07-2006 03:55 AM

Thank you chrism01!


Quote:

Originally Posted by chrism01
The script exits with the result value of the last cmd run. If you want to set it explictly, use
exit <some_positive_integer_or_zero>
conventionally on Unix style systems, zero is success, (positive) int is an error. iirc, negative value is not allowed here.

Do you know whether there is some default value to return if we do not write exit on the last line of a script file?


regards,
George

George2 05-07-2006 03:58 AM

Thank you taylor_venable!


Quote:

Originally Posted by taylor_venable
From the manual page: "The env utility executes another utility after modifying the environment as specified on the command line. ... Probably the most common use of env is to find the correct interpreter for a script, when the interpreter may be in different directories on different systems. The following example will find the `perl' interpreter by searching through the directories specified by PATH."
Code:

#!/usr/bin/env perl
In other words, env applies an environment (the current one, modified by options passed to env) to an executable. So actually, you can use env to specify all kinds of environment variables, including PATH and LD_LIBRARY_PATH, so that things are just right when the script gets executed. This feature would be increasingly useful in varied environments. The env binary is stored in /usr/bin on all three of the major BSDs, and also on Slackware Linux, in my experience. I think it's somewhat of a standard, so it should be there on other systems as well, but you'll have to check to be sure.

What do you mean "the current one, modified by options passed to env"? I think you mean passing parameter to env -- but I am not sure about it. Could you show me an example to show your idea please?


regards,
George

taylor_venable 05-07-2006 01:10 PM

I mean, the current environment is applied to the program that env is going to execute. And by passing VARIABLE=value options to env, you can modify that environment. For example:
Code:

#!/usr/bin/env -S MY_ENV_VARIABLE=foo bash

echo -n "MY_ENV_VARIABLE = "
echo $MY_ENV_VARIABLE
echo -n "PWD = "
echo $PWD

MY_ENV_VARIABLE probably won't exist before the script starts executing. But when you call env, it creates the variable MY_ENV_VARIABLE and assigns "foo" to it. Then the env utility runs bash, which takes over interpretation on the rest of the script. And now a historical note on the significance of the -S option, courtesy of the FreeBSD env manual page:
Quote:

Note that the way the kernel parses the `#!' (first line) of an interpreted script has changed as of FreeBSD 6.0. Prior to that, the FreeBSD kernel would split that first line into separate arguments based on any whitespace (space or <tab> characters) found in the line. So, if a script named /usr/local/bin/someport had a first line of:
Code:

#!/usr/local/bin/php -n -q -dsafe_mode=0
then the /usr/local/bin/php program would have been started with the arguments of:
Code:

arg[0] = '/usr/local/bin/php'
arg[1] = '-n'
arg[2] = '-q'
arg[3] = '-dsafe_mode=0'
arg[4] = '/usr/local/bin/someport'

plus any arguments the user specified when executing someport. However, this processing of multiple options on the `#!' line is not the way any other operating system parses the first line of an interpreted script. So after a change which was made for FreeBSD 6.0 release, that script will result in /usr/local/bin/php being started with the arguments of:
Code:

arg[0] = '/usr/local/bin/php'
arg[1] = '-n -q -dsafe_mode=0'
arg[2] = '/usr/local/bin/someport'

plus any arguments the user specified. This caused a significant change in the behavior of a few scripts. In the case of above script, to have it behave the same way under FreeBSD 6.0 as it did under earlier releases, the first line should be changed to:
Code:

#!/usr/bin/env -S /usr/local/bin/php -n -q -dsafe_mode=0
The env utility will be started with the entire line as a single argument:
Code:

arg[1] = '-S /usr/local/bin/php -n -q -dsafe_mode=0'
and then -S processing will split that line into separate arguments before executing /usr/local/bin/php.
In other words, the "-S" is pretty important if you do anything more complicated than
Code:

/usr/bin/env bash
by passing options to env and/or bash. If the manual is correct, this should be available on many systems, but I only have BSD systems so I can't check it out for you.

George2 05-08-2006 02:22 AM

Thanks taylor_venable!


Quote:

Originally Posted by taylor_venable
I mean, the current environment is applied to the program that env is going to execute. And by passing VARIABLE=value options to env, you can modify that environment. For example:
Code:

#!/usr/bin/env -S MY_ENV_VARIABLE=foo bash

echo -n "MY_ENV_VARIABLE = "
echo $MY_ENV_VARIABLE
echo -n "PWD = "
echo $PWD

MY_ENV_VARIABLE probably won't exist before the script starts executing. But when you call env, it creates the variable MY_ENV_VARIABLE and assigns "foo" to it. Then the env utility runs bash, which takes over interpretation on the rest of the script. And now a historical note on the significance of the -S option, courtesy of the FreeBSD env manual page:In other words, the "-S" is pretty important if you do anything more complicated than
Code:

/usr/bin/env bash
by passing options to env and/or bash. If the manual is correct, this should be available on many systems, but I only have BSD systems so I can't check it out for you.

I have tried your method on my Red Hat Linux system, but the behavior is quite different.

In the below scripts,

Code:

#!/usr/bin/env -S FOO=foo GOO=goo bash
echo $FOO
echo $GOO

From the output, it seems that the -S option is not supported.

Code:

[root@localhost root]# ./test3.sh
/usr/bin/env: invalid option -- S
Try `/usr/bin/env --help' for more information.

When I remove the -S option, the script will be pending and it seems that it will not end it execution, like this,

Code:

#!/usr/bin/env FOO=foo GOO=goo bash
echo $FOO
echo $GOO

Output,

Code:

[root@localhost root]# ./test3.sh

regards,
George


All times are GMT -5. The time now is 10:23 AM.