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
How to Check If a Key Was Pressed in Linux
Bash: Inserting a Line in a File at a Specific Location
Why Doesn't Linux Use the Hardware Context Switch via the Tss
Writing a Putchar in Assembly for X86_64 with 64 Bit Linux
Unix Standard Directory to Put Custom Executables or Scripts
How to Configure Linux Capabilities Per User
How to Get the Difference (Only Additions) Between Two Files in Linux
Sed with Literal String--Not Input File
Best Practice to Run Linux Service as a Different User
Command to Change the Default Home Directory of a User
Merge PDF's with PDFtk with Bookmarks
Difference Between Posix Aio and Libaio on Linux
How Does Vi Restore Terminal Content After Quitting It