shell script interpreter not identifying the path - shell

I can successfully run the following command in the shell.
export ANT_HOME=/users/user1/workspace/apache-ant-1.7.0
But when I am adding the same line in a shell script, I am getting the following error.
`/users/user1/workspace/apache-ant-1.7.0': not a valid identifier
The shell interpreter is taking -1.7.0 in the path as a arithmetic operation.
How can I fix this ?
EDIT : the shell script which I am trying to run is here.
#!/bin/sh
settingsForANT()
{
export ANT_HOME=/users/user1/workspace/apache-ant-1.7.0
export PATH=${PATH}:${ANT_HOME}/bin
echo $ANT_HOME
echo $PATH
}
settingsForANT

Most likely you either have a $ before the ANT_HOME or a space after the =, probably the latter.
It's complaining about your path being an invalid identifier, meaning it's on the left hand of an assignment, not the right.
If that turns out to be not the case, check the shell you're running the script as. Some do not allow combined set/export and you may need:
ANT_HOME=whatever; export ANT_HOME

Related

shell program to build a stack in Linux ubuntu [duplicate]

How to set a global environment variable in a bash script?
If I do stuff like
#!/bin/bash
FOO=bar
...or
#!/bin/bash
export FOO=bar
...the vars seem to stay in the local context, whereas I'd like to keep using them after the script has finished executing.
Run your script with .
. myscript.sh
This will run the script in the current shell environment.
export governs which variables will be available to new processes, so if you say
FOO=1
export BAR=2
./runScript.sh
then $BAR will be available in the environment of runScript.sh, but $FOO will not.
When you run a shell script, it's done in a sub-shell so it cannot affect the parent shell's environment. You want to source the script by doing:
. ./setfoo.sh
This executes it in the context of the current shell, not as a sub shell.
From the bash man page:
. filename [arguments]
source filename [arguments]
Read and execute commands from filename in the current shell
environment and return the exit status of the last command executed
from filename.
If filename does not contain a slash, file names in PATH are used to
find the directory containing filename.
The file searched for in PATH need not be executable. When bash is not
in POSIX mode, the current directory is searched if no file is found
in PATH.
If the sourcepath option to the shopt builtin command is turned off,
the PATH is not searched.
If any arguments are supplied, they become the positional parameters
when filename is executed.
Otherwise the positional parameters are unchanged. The return status
is the status of the last command exited within the script (0 if no
commands are executed), and false if filename is not found or cannot
be read.
source myscript.sh is also feasible.
Description for linux command source:
source is a Unix command that evaluates the file following the command,
as a list of commands, executed in the current context
#!/bin/bash
export FOO=bar
or
#!/bin/bash
FOO=bar
export FOO
man export:
The shell shall give the export attribute to the variables corresponding to the specified names, which shall cause them to be in the environment of subsequently executed commands. If the name of a variable is followed by = word, then the value of that variable shall be set to word.
A common design is to have your script output a result, and require the cooperation of the caller. Then you can say, for example,
eval "$(yourscript)"
or perhaps less dangerously
cd "$(yourscript)"
This extends to tools in other languages besides shell script.
In your shell script, write the variables to another file like below and source these files in your ~/.bashrc or ~/.zshrc
echo "export FOO=bar" >> environment.sh
In your ~/.bashrc or ~/.zshrc, source it like below:
source Path-to-file/environment.sh
You can then access it globally.
FOO=bar
export FOO

Make: Set shell and source a file at the same time?

Suppose I would like to set a shell in make:
SHELL:=/usr/bin/env bash
Next, suppose I have some runcom/bash file I would like to source as well. This file optionally activates a virtual environment:
if [ -d venv ]; then source venv/bin/activate fi;
However, if I write:
SHELL:=/usr/bin/env bash && source runcom/bash
This fails. However, if I deposited the venv logic into the local ~/.bashrc and write:
SHELL:=/usr/bin/env bash -l
I can get the exact functionality I need.
But, I have to deposit something that should remain downstream from the local user into the user's upstream environment -- I'd rather not.
Is there a way to get the make shell to source a file at the declaration step in the make start-up process?
This can't work:
SHELL:=/usr/bin/env bash && source runcom/bash
Because SHELL tells make how to invoke the shell; if you make the contents of SHELL be a shell script then make has to invoke the shell to interpret how to invoke the shell, which means it has to invoke the shell to invoke the shell to interpret how to invoke the shell, etc.
So, SHELL must be either a simple command or, at most, a simple set of arguments that can converted into an argv list and passed to exec(2).
So, this is really a shell question not a make question: how can you get the shell to source arbitrary stuff when it starts without changing ~/.profile or whatever?
Luckily, this is possible; see the bash man page:
BASH_ENV
If this parameter is set when bash is executing a shell script,
its value is interpreted as a filename containing commands to
initialize the shell, as in ~/.bashrc. The value of BASH_ENV is
subjected to parameter expansion, command substitution, and
arithmetic expansion before being interpreted as a filename.
PATH is not used to search for the resultant filename.
ENV Similar to BASH_ENV; used when the shell is invoked in posix
mode.
So, in your makefile you can use something like:
SHELL := /bin/bash
export BASH_ENV := runcom/bash
and that should be sufficient.

How can I store and execute the command "export PATH=$PREFIX/bin" from a script?

I would like to write a script that has several commands of the kind
> export PATH=$PREFIX/bin
Where
> $PREFIX = /home/usr
or something else. Instead of typing it into the the Shell (/bin/bash) I would run the script to execute the commands.
Tried it with sh and then with a .py script having the line,
> commands.getstatusoutput('export PATH=$PREFIX/bin')
but these result into the error "bad variable name".
Would be thankful for some ideas!
If you need to adjust PATH (or any other environment variable) via a script after your .profile and equivalents have been run, you need to 'dot' or 'source' the file containing the script:
. file_setting_path
source file_setting_path
The . notation applies to all Bourne shell derivatives, and is standardized by POSIX. The source notation is used in C shell and has infected Bash completely unnecessarily.
Note that the file (file_setting_path) can be specified as a pathname, or if it lives in a directory listed on $PATH, it will be found. It only needs to be readable; it does not have to be executable.
The way the dot command works is that it reads the named file as part of the current shell environment, rather than executing it in a sub-shell like a normal script would be executed. Normally, the sub-shell sets its environment happily, but that doesn't affect the calling script.
The bad variable name is probably just a complaint that $PREFIX is undefined.
Usually a setting of PATH would look something like
export PATH=$PATH:/new/path/to/programs
so that you retain the old PATH but add something onto the end.
You are best off putting such things in your .bashrc so that they get run every time you log in.

How to run cd within bash script (outside of subshell)

I am writing a bash script (called gotodir.sh) and would like to change directories during the course of the script, depending on some variables, say cd /home/username/${FOO}/${BAR}.
Just running this as is doesn't work when the process exits, since the directory was changed in the subshell only.
My shell is tcsh. (Yeah, I know... not my choice here.) In my .cshrc file, I want to alias the keyword gotodir to gotodir.sh.
I have read that executing the script with a . or source prefix will cause the script to be run in the same shell (i.e. not a subshell).
I have tried putting the following in my .cshrc file:
alias gotodir . /home/username/bin/gotodir.sh
but this results in the error: /bin/.: Permission denied.
I have also tried using source instead of .
alias gotodir source /home/username/bin/gotodir.sh
but this results in the error: if: Expression Syntax.
How do I accomplish this using a bash script while running tcsh?
When you source a file from tcsh, it tcsh runs the commands. The #! is ignored as a comment because you're not running the file as a script, just reading commands from it as if they'd been entered at the shell prompt.
Your mission is doomed to failure. Only a tcsh cd command can change the current directory of a tcsh process.
But if you're willing to bend a little, you can write a script which runs as a separate process and outputs the name of the directory to cd to. Then set the alias like
alias gotodir 'cd `/blah/blah/thescript`'
Addendum
Adding an argument is possible, but tricky. Alias arguments look like history expansion, with !:1 expanding to the first argument. But quotes don't protect the ! character. You have to backslash it to prevent it being expanded during creation of the aliase, so it can do its work during the execution of the alias.
alias gotodir 'cd `/blah/blah/thescript \!:1`'
Additional quoting may be required to handle arguments and directories with spaces in them.

Global environment variables in a shell script

How to set a global environment variable in a bash script?
If I do stuff like
#!/bin/bash
FOO=bar
...or
#!/bin/bash
export FOO=bar
...the vars seem to stay in the local context, whereas I'd like to keep using them after the script has finished executing.
Run your script with .
. myscript.sh
This will run the script in the current shell environment.
export governs which variables will be available to new processes, so if you say
FOO=1
export BAR=2
./runScript.sh
then $BAR will be available in the environment of runScript.sh, but $FOO will not.
When you run a shell script, it's done in a sub-shell so it cannot affect the parent shell's environment. You want to source the script by doing:
. ./setfoo.sh
This executes it in the context of the current shell, not as a sub shell.
From the bash man page:
. filename [arguments]
source filename [arguments]
Read and execute commands from filename in the current shell
environment and return the exit status of the last command executed
from filename.
If filename does not contain a slash, file names in PATH are used to
find the directory containing filename.
The file searched for in PATH need not be executable. When bash is not
in POSIX mode, the current directory is searched if no file is found
in PATH.
If the sourcepath option to the shopt builtin command is turned off,
the PATH is not searched.
If any arguments are supplied, they become the positional parameters
when filename is executed.
Otherwise the positional parameters are unchanged. The return status
is the status of the last command exited within the script (0 if no
commands are executed), and false if filename is not found or cannot
be read.
source myscript.sh is also feasible.
Description for linux command source:
source is a Unix command that evaluates the file following the command,
as a list of commands, executed in the current context
#!/bin/bash
export FOO=bar
or
#!/bin/bash
FOO=bar
export FOO
man export:
The shell shall give the export attribute to the variables corresponding to the specified names, which shall cause them to be in the environment of subsequently executed commands. If the name of a variable is followed by = word, then the value of that variable shall be set to word.
A common design is to have your script output a result, and require the cooperation of the caller. Then you can say, for example,
eval "$(yourscript)"
or perhaps less dangerously
cd "$(yourscript)"
This extends to tools in other languages besides shell script.
In your shell script, write the variables to another file like below and source these files in your ~/.bashrc or ~/.zshrc
echo "export FOO=bar" >> environment.sh
In your ~/.bashrc or ~/.zshrc, source it like below:
source Path-to-file/environment.sh
You can then access it globally.
FOO=bar
export FOO

Resources