csh script as executable does not setenv - environment-variables

I am not able to set env variables through an executable csh/tcsh script
An env variable set inside a csh/tcsh executable script "myscript"
contents of the script ...
setenv MYVAR /abc/xyz
which is not able to set on the shell and reports "Undefined variable"
I have made the csh/tcsh script as executable by the following shell command
chmod +x /home/xx/bin/myscript
also the path is updated to
set path = (/home/xx/bin $path)
which myscript
/home/xx/bin/myscript
When I run the script on command line and echo the env variable ..
myscript
echo $MYVAR
MYVAR "Undefined variable"
but if i source on command line
source /home/xx/bin/myscript
echo $MYVAR
/abc/xyz

you need to source your code rather than execute it so that it is evaluated by the current shell where you want to modify the environment.
You can of course embed
source /home/xx/bin/myscript
within your .cshrc
the script does not need to be executable or have any #! shebang (though they don't hurt)

This is not how environment variables work.
An environment variable is set for a process (in this case, tcsh) which is passed on to all child processes. So when you do:
$ setenv LS_COLORS=foo
$ ls
You first set LS_COLORS for the tcsh process, tcsh then starts the child process ls which inheres tcsh's environment (including LS_COLORS), which it can then use.
However, what you're doing is setting the environment is a child process, and then want to propagate this back to the parent process (somehow). This is not possible. This has nothing to do with tcsh, it works like this for any process on the system.
It works with source because source reads a file, and executes it line-by-line in the current process. So it doesn't start a new tcsh process.
I will leave it as an exercise to you what the implications would mean if it would be possible :-) Do you really want to deal with unwise shell scripts that set some random environment variables? And what about environment variables set by a php process, do we want those to go back in the parent httpd process? :-)
You didn't really describe what goal you're trying to achieve, but in general, you want to do something like:
#!/bin/csh -f
# ... Do stuff ...
echo "Please copy this line to your environment:"
echo "setenv MYVAR $myvar"

Related

conditional set of a variable based on another ENV variable [duplicate]

This question already has answers here:
Conditional ENV in Dockerfile
(8 answers)
Closed 3 years ago.
In a given Dockerfile, I want to set a variable based on content of another ENV variable (which is injected into the container beforehand, or defined within the Dockerfile)
I'm looking at something like this
FROM centos:7
ENV ENABLE_REMOTE_DEBUG "true"
ENV DEBUG_FLAG=""
RUN if [ "$ENABLE_REMOTE_DEBUG" = "true" ] ; then echo "set debug flag" ;export DEBUG_FLAG="some_flags"; else echo "remote debug not set" ; fi
RUN echo debug flags: ${DEBUG_FLAG}
## Use the debug flag in the Entrypoint : java jar ${DEBUG_FLAG} ...
the problem with this Dockerfile is $DEBUG_FLAG is not properly set (or is not being used in the next line? ) ... since output is empty:
debug flags:
What am I missing here? (I prefer not to call external bash script)
Let’s take a look at what’s going on when a Dockerfile is used to build a Docker image.
Each line, is executed in a fresh container. The resulting container state, after the line has been interpreted, is saved in a temporary image and used to start a container for the next command.
This temp image do not save any state apart from the files on disk, Docker-specific properties like EXPOSE and a few image settings. Temp images has the advantage of fast subsequent builds using cache.
Now come to your question, if you would want to do using RUN instead of writing in shell script, here is a work around
RUN if [ "$ENABLE_REMOTE_DEBUG" = "true" ] ; then echo "set debug flag" ;echo 'export DEBUG_FLAG="some_flags"' >>/tmp/myenv; else echo "remote debug not set" ; fi
RUN source /tmp/myenv;echo debug flags: ${DEBUG_FLAG}
Since the image is based on CentOS, the default shell is bash, thus sourcing your own environment file will work fine. In other shells where source might not work, then reading the file will help.
You cannot set environment variables using export in RUN instruction and expect to them to available in next instruction. Only filesystem changes created by RUN instruction are persisted. Other stuff like environment variables etc are discarded.
You should move the logic to a shell script.

Explain the different parts of the code needed to add $HOME/.rbenv/bin to your $PATH

I understand the code is trying to make the executable in $HOME/.rbenv/bin available in $PATH so it can be executed from the command line but I can't figure out how the code does this. The code is shown below:
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> $HOME/.bashrc.
I know that something is being appended to the end of the bashrc file and I know export is used to export environment variables to new shells but I don't see any new shell here. And I have seen echo used in the following way: a = 5; echo $a but I can't figure out why you need it here and what is
PATH="$HOME/.rbenv/bin:$PATH"
doing. what does 'PATH' represent. Is it a variable without the $ and what is 'bin:$PATH'.
In bash (and most other shells) you assign variables without the $, so PATH=something assigns the variable PATH to the string "something".
In Unix/ Linux, PATH is a string variable that contains a list of folders separated by colons (:). For example on my laptop this is my PATH:
> echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
This means that any executable in those folders is accessible anywhere without having to type the full path. You will typically add things to the PATH in your .bashrc file, so they get added when your shell starts up. If you use the which command you can see where a command lives, it will be in one of these folders:
> which rm
/bin/rm
To add a new folder to the PATH, you re-assign PATH to be a string of the new folder, followed by a colon and the previous value of PATH.
In you example, you are adding $HOME/.rbenv/bin to the start of PATH. $HOME will be expanded to your home directory.
To understand this better we can do something like this:
> echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
> export PATH="$HOME/.rbenv/bin:$PATH"
> echo $PATH
/Users/javanut13/.rbenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
As you can see the rbenv folder was added to the front of the PATH variable.
export puts the variable into the environment of the current shell, which means that other commands started in that shell (subprocesses) also get this change. For example if you don't do export and then run a bash script that uses ruby, it will fail because it doesn't have the ~/.rbenv/bin folder in its path.

Unable to set environment variables using source ~/.profile in script

So I have a script, and I'm setting an environment variable using:
echo 'export env_var=hello' >> ~/.profile
source ~/.profile
When the script completes, I check the existence of this environment variable by doing:
echo $env_var
Which gives me "" rather than "hello". If I run source ~/.profile on my terminal (typed straight up in the terminal, not called from any script) , the environment variable will be set correctly. Why is my script unable to set the environment variable correctly, and what do I need to do for it to do so?
env_var is being export-ed all right, but in the subshell (and its children) the script is being executed on.
When you execute an= script, the script is run on a subshell, which is a child of the calling shell, so after the script finishes, the exported variables go out of scope from calling shell's point of view.
A common practice to have all the variables (and other data structures) available in the calling shell, is to source (.) the script, not execute it, which you are doing but from the script, not from the interactive session.

How can I run a bash command in Ruby?

I have a script in Ruby and inside has to run a bash command. This command is an export http_proxy = "" and export https_proxy = "".
The problem is that I run the following, without running errors, but appears that doesn't make any change:
system "export http_proxy=''"
system "export https_proxy=''"
I created a file.sh with this lines and if I run it in a terminal only works when run: source file.sh or . file.sh.
Could you please help me how I can run this commands in the Ruby script? It can be directly with the command lines or executing an .sh file in the script.
When you run a separate process using system, any changes made to the environment of that process affects that process only, and will disappear when the process exits.
That exactly why running file.sh won't change your current shell since it runs it as a sub-shell, and the changes disappear when the process exits.
As you've already discovered, using source or . runs deoes affect the current shell but that's because it runs the script not as a sub-shell, but within the context of the current shell.
If you want to change the environment variables of the current Ruby script, you should look into ENV, something like:
ENV["http_proxy"] = ""
ENV["https_proxy"] = ""
%x( echo 'hi' )
and to capture standard output in a variable
var = %x( echo 'hi' )

Edit bash PATH variable for Rails application

I have application minizinc in file ~/.bashrc, and I can call it on bash. I am building a Rails application that calls minizinc from bash, but I cannot do it. After executing this:
#cmd = ` bash -c "minizinc #{path} -n 1" `
I get the following error:
bash: minizinc: command not found
How can I change the Rails application user's PATH variable from the application? Or how do I tell the Rails application where this bash application is located?
You have several options here. The one I think best suits your case and would recommend is using the command directly, instead of calling Bash to do the same as Ruby:
#cmd = `minizinc #{path} -n 1`
If you use it like this, the command is executed in a shell with an environment similar to the one where Ruby is running. Which means that the PATH variable will be the same. So if the dir containing the executable minizinc is in PATH when you start the Rails server, it should also be in the PATH variable of the shell running that command.
Now, if you really need to use Bash in the middle, I strike it as odd that the PATH variable is not the same as in Ruby (I tried it using IRB and seems to work as expected). You can check it by replacing your command with
bash -c "echo $PATH"
It should print the same value as
puts ENV['PATH']
when run in the Rails console.
If, after checking it, you see that the PATH variable of your Rails environment is incorrect, you can set it specifically for the Rails server:
PATH="<path_to_minizinc_dir>:$PATH" rails server
This sets the value of the PATH environment variable only for the command you are about to execute, in this case rails server.
Alternatively, you can surpass all this by simply using the absolute path to the executable:
#cmd = `bash -c "/full/path/to/minizinc #{path} -n 1"`
If you provide the full path to the command you want to execute, the PATH environment variable simply won't come into play, but I imagine this would be suboptimal for your case.

Resources