How to Run a Script on Login in *Nix

How do you run a script on login in *nix?

From wikipedia Bash

When Bash starts, it executes the commands in a variety of different
scripts.

When Bash is invoked as an interactive
login shell, it first reads and
executes commands from the file
/etc/profile, if that file exists.
After reading that file, it looks for
~/.bash_profile, ~/.bash_login, and
~/.profile, in that order, and reads
and executes commands from the first
one that exists and is readable.

When a login shell exits, Bash reads
and executes commands from the file
~/.bash_logout, if it exists.

When an interactive shell that is not
a login shell is started, Bash reads
and executes commands from ~/.bashrc,
if that file exists. This may be
inhibited by using the --norc option.
The --rcfile file option will force
Bash to read and execute commands from
file instead of ~/.bashrc.

Run a Bash Script automatically upon login on Unix

If you already had a ~/.profile file it should be fine to just add it there. Otherwise look for a ~/.bash_profile and add the line there.

Did you make sure that your file is executable? Otherwise it will not work.
Here is an example code (make sure to adapt to your needs):

echo "echo 'foo'" > /tmp/execute_me 
chmod u+x /tmp/execute_me
echo "/tmp/execute_me" >> ~/.profile

login from another console (for safety), and you should see "foo" printed in your console somewhere.

If you want your script to be executed whenever a shell is used (even not interactive, you should add the code to the ~/.bashrc, read this for details: https://unix.stackexchange.com/questions/129143/what-is-the-purpose-of-bashrc-and-how-does-it-work)

Writing One Shell script to first enter nix shell, then enter the python virtual environment

Shell scripts are a bit different from interactive sessions in the terminal.

When you run nix-shell in your terminal, the original shell process creates a nix-shell process and lets it read your input until nix-shell exits, returning control to the original shell.

In a shell script on the other hand, the shell will read all lines by itself and will not delegate the processing of the shell script to other executables like nix-shell. *

If you want to run all comamnds in the nix-shell, you can use a special shebang at the top of the file. For example:

#!/usr/bin/env nix-shell
#!nix-shell -p python38Full -p python38Packages.virtualenv
#!nix-shell -i bash
source .venv/bin/activate

# insert commands to be run here

/usr/bin/env is just a helper to look up nix-shell without an absolute path.
nix-shell is run as a script interpreter that will parse #!nix-shell lines for its own options.
The -i bash option tells it to invoke bash as the actual interpreter for this script.
bash ignores the shebang and #!nix-shell lines, because they're comments. nix-shell has set the right environment variables in advance. It continues to source the activate file.

You might want to generate the activate script before running source, but I suppose that depends on your workflow.

Alternatively, you could use the --run COMMAND option of nix-shell to run single commands in the context provided by Nix.


*: commands in parentheses do run in a separate process, but this is mostly an implementation detail. It won't let other programs take over the execution of the script.

run commands using default.nix file

As per wizzup's comment, this was solved using shellHook:

#default.nix
with import <nixpkgs> {}; {
pullapiEnv = stdenv.mkDerivation {
name = "pullapi";
buildInputs = [ elixir ];
shellHook = ''
mix deps.get
mix compile
mix test
'';
};
}

Nix shell #! to refer to to shell.nix in a parent directory

The items after #! nix-shell are basically regular nix-shell arguments, so you can add the file name like this.

#!/usr/bin/env nix-shell
#! nix-shell -i bash ../shell.nix
set -e

Path resolution happens relative to the script file.
When you use a directory path, it will look for default.nix, not shell.nix inside the directory.

Why does `runScript =` in `buildFHSUserEnv` stop after first line when using two single quotes?

runScript isn't treated as a proper bash script, but is rather pasted directly after the beginning of an exec statement.

The generated code becomes either

exec
echo one
echo two

or

exec echo one
echo two

because '' removes the starting newline.

exec by itself is a no-op in bash, so that happens to behave as expected, but exec echo one replaces the shell interpreter by an echo one process, which is not what you intended.

Seems like the runScript parameter should be deprecated and replaced by two optional ones which are self-explanatory, unless this behavior is caused by a recent change, which would make it a regression (bug).

Unable to run user script in Unix server from Windows using C# and SSH.NET

Your question is pretty vague.

But first, I'd try is to add a path to the script. Either absolute (/home/user/script) or relative (./script).

*nix shells by default do not look for executables in the current working directory (home directory in this case). They find them only, if you have . in your PATH.

Note that the RunCommand uses a non-interactive session. It may have a different environment (PATH) than the interactive session you use in the SSH terminal. Different set of start-up scripts is used for interactive and non-interactive sessions.



Related Topics



Leave a reply



Submit