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

I start almost all my scripts lately with
#!/usr/bin/env nix-shell
#! nix-shell -i bash
set -e
But this requires that the default.nix/shell.nix be in the same directory as the script which is not always the case. Is there a way to tell nix-shell to look at all parent directories for a *.nix file?

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.

Related

How to see the PATH inside a shell without opening a shell

Use the command flag looked like a solution but it doesn't work
Inside the following shell:
nix shell github:nixos/nixpkgs/nixpkgs-unstable#hello
the path contain a directory with an executable hello
I've tried this:
nix shell github:nixos/nixpkgs/nixpkgs-unstable#hello --command echo $PATH
I can't see the hello executable
My eyes are not the problem.
diff <( echo $PATH ) <( nix shell github:nixos/nixpkgs/nixpkgs-unstable#hello --command echo $PATH)
It see no difference. It means that the printed path doesn't not contains hello.
Why?
The printed path does not contain hello because if your starting PATH was /nix/var/nix/profiles/default/bin:/run/current-system/sw/bin, then you just ran:
nix shell 'github:nixos/nixpkgs/nixpkgs-unstable#hello' --command \
echo /nix/var/nix/profiles/default/bin:/run/current-system/sw/bin
That is to say, you passed your original path as an argument to the nix shell command, instead of passing it a reference to a variable for it to expand later.
The easiest way to accomplish what you're looking for is:
nix shell 'github:nixos/nixpkgs/nixpkgs-unstable#hello' --command \
sh -c 'echo "$PATH"'
The single quotes prevent your shell from expanding $PATH before a copy of sh invoked by nix is started.
Of course, if you really don't want to start any kind of child shell, then you can run a non-shell tool to print environment variables:
nix shell 'github:nixos/nixpkgs/nixpkgs-unstable#hello' --command \
env | grep '^PATH='

Best practice to include a bash script in a Docker image

I'm creating a Dockerfile that needs to execute a command, let's call it foo
In order to execute foo, I need to create a .cfc in current directory with token information to call this foo service.
So basically I should do something like
ENV FOO_TOKEN token
ENV FOO_HOST host
ENV FOO_SHARED_DIRECTORY directory
ENV LIBS_TARGET target
and then put the first three variables in a .cfg file and then launch a command using the last variable as target.
Given that if run more than one CMD in a Dockerfile, only the last one will be considered, how should I do that?
My ideal execution is docker run -e "FOO_TOKEN=aaaaaaa" -e "FOO_HOST=myhost" -e "FOO_SHARED_DIRECTORY=Shared" -e "LIBS_TARGET=target/scala-2.11/*.jar" -it --rm --name my-ci-deploy foo/foo:latest
If you wanted to keep everything in the Dockerfile (something I think is rather desirable), you can do something nasty like:
ENV SCRIPT=IyEvdXNyL2Jpbi9lbnYgYmFzaApwZG9fc3Fsc3J2PTAKc3Vkbz0KdmVuZG9yPSQoIGxzYl9yZWxlYXNlIC1p
RUN echo -n "$SCRIPT" | base64 -d | /usr/bin/env bash
Where the contents of SCRIPT= are derived by piping your shell script thusly:
cat my_script.sh | base64 --wrap=0
You may have to adjust the /usr/bin/env bash if you have a really minimal (Alpine) setup.

How to run a command on the startup of an xterm?

How can I run a command on xterm startup i.e. when an xterm terminal is launched a the command is already executed?
I have edited the .bashrc file to add this line:
xterm "ls"
But this does not work.
Please suggest what should I do to acheive this.
Thanks.
According to the bash manual, ~/.bashrc is used for interactive shells. xterm runs a shell, so perhaps your "does not work" causes a chain of xterm's.
The xterm program sets these environment variables which are useful for scripting: XTERM_VERSION and XTERM_SHELL. In your ~/.bashrc file, you could use the former to run the xterm -ls once only:
if [[ -z "$XTERM_VERSION" ]]
then
xterm -hold -e ls &
fi
which seems to be what you are asking for:
it would run an xterm if not run from an existing xterm
it prevents the xterm from closing when the ls is done.
A more useful-seeming way of showing an ls on shell startup would be to run ls in each shell as it is started (for that case, you do not need run a separate xterm). Again, you can use environment variables to do this once (in case you run bash to make a subshell):
if [[ -z "$XTERM_ONCE" ]]
then
export XTERM_ONCE=$(date)
ls
fi
I use this:
-e /bin/bash -login
-e command [arguments]
Run the command with its command-line arguments in the rxvt window;
also sets the window title and icon name to be the basename of the
program being executed if neither -title (-T) nor -n are given on the
command line. If this option is used, it must be the last on the
command-line. If there is no -e option then the default is to run the
program specified by the SHELL environment variable or, failing that,
sh(1).
http://linux.die.net/man/1/rxvt

Add folder to sudo path without -i

There has been a lot of talk already done on Stack Overflow about adding a folder to the sudo path. But, none of the other tutorials I've seen have really answered the following question:
How can I add a folder to the sudo PATH without using -i.
Here is my setup. The folder I want to add is "/var/folder". There is the bash script "/var/folder/script.sh". I added the following lines of code to the /root/.bashrc file:
if [ -d /var/folder ]; then
PATH=/var/folder:$PATH
fi
Now, when I type in the command "sudo echo $PATH" I get the following output:
/var/folder:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
The problem is, when I run the command "sudo script.sh", the script can't seem to be found. The output is as follows:
sudo: script.sh: command not found
This is in spite of the fact that tab-auto-complete works on "sudo script.sh".
All though the $PATH is defined when you do an echo of it, for running the script it is not actually defined. So to see what is happening, you can run the following:
sudo -s
echo $PATH
You will notice that it will be:
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
Where is it getting the $PATH from?
It is defined in your sudoers file:
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Solution
You can update the Defaults secure_path in the sudoers file to have the correct value.
Defaults secure_path="/var/folder:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Going back to how you were seeing the correct value when you ran:
sudo echo $PATH
Since you had $PATH defined with /var/folder before you ran that command, it just replaced the $PATH with the value, but your actual path for sudo was
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
so you were effectively running
sudo echo /var/folder:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

PHP CLI - something like $PATH

I want to ask you if there is something like UNIX $PATH for PHP CLI.
Eg., I want to use
php a2addvhost.php example.com
instead of
php /usr/share/php/a2addvhost.php example.com
I tried to change include_path and $PATH but either work.
If you're doing
php a2addvhost.php example.com
You're still in Unix. So the a2addvhost.php file must be in the current directory for it to work.
The first argument must be the exact pathname. However, you can make a start script (as root):
$ echo -e '#!/bin/sh\nexec php /usr/share/php/a2addvhost.php "$#"\n' \
> /usr/bin/a2addvhost
$ # And then start with ...
$ a2addvhost example.com
Alternatively, make a2addvhost.php executable by prepending it as follows:
#!/usr/bin/env php
<?php
/* php code goes here */
and making it executable:
$ chmod a+x /usr/share/php/a2addvhost.php
Now, if PATH contains /usr/share/php/, you can start your script with
$ /usr/share/php/a2addvhost.php example.com
Add /usr/share/php/ to your PATH, give it the executable flag, then simply run
a2addvhost.php example.com
you may need to add the shebang at the beginning of the file.

Resources