How can I tell a Linux Script (ash, not bash) is running "sourced"? - linux

How can I tell in an ash script if it is running "sourced" or "normal"? By sourced I mean using the "." or "source" command to launch the script in the current shell.

Not sure if it's the best option (will not work if the script has the same name as the shell), but you can check the first parameter ($0). Example:
$ cat test.sh
#!/bin/ash
echo "Value: $0"
$ ./test.sh
Value: ./test.sh
$ source test.sh
Value: ash
If you want to check if the file was sourced, you can use something like this:
#!/bin/ash
case $0 in
ash) echo "Sourced" ;;
*) echo "Not sourced" ;;
esac

Related

Define environment variable in a subshell with heredoc

Background: testing a bash script inside a pod where default user does not have sudo rights so that user cannot user vim or nano to create a .sh file so I have to find a way around with cat << EOF >> test.sh.
I am doing some local test to make sure it's working properly first. Locally I am creating a file test.sh with nano. See below
#!/bin/bash
# test.sh
VAR="Test"
echo $VAR
When I cat it:
#!/bin/bash
# test.sh
VAR="Test"
echo $VAR%
I save test.sh , made it execuatble chmod +x test.sh and ran it with ./test.sh The output:
Test
Now when I try to mimic the same behavior in a bash heredoc instead this is the command I use:
cat <<EOF >> test.sh
#!/bin/bash
# test.sh
VAR="Test"
echo $VAR
EOF
I saved it and made it execuatble as well. The cat output is:
#!/bin/bash
# test.sh
VAR="Test"
echo
So obviously running it wouldn't work. The output null.
I think the issue I am facing is that the environment variable $VAR is not defined properly inside the subshell using heredoc.
When you write this:
cat <<EOF >> test.sh
#!/bin/bash
# test.sh
VAR="Test"
echo $VAR
EOF
...that $VAR is expanded by your current shell (just like writing something like echo "$VAR"). If you want to suppress variable expansion inside your heredoc, you can quote it (note the quotes around 'EOF'):
cat <<'EOF' >> test.sh
#!/bin/bash
# test.sh
VAR="Test"
echo $VAR
EOF
This inhibits variable expansion just like single quotes (echo '$VAR').

How can I get the current script name of a script running in parent script's shell?

How can I get the name of a child script that is running in the shell of it's parent?
consider script1.sh;
#this is script 1
echo "$0"
. ./script2.sh
and script2.sh;
#this is script 2
echo "$0"
Since script2.sh is being executed in [sourced from] the same shell as script1.sh, the output of running these scripts are both;
./script1.sh
How can get the name of script2.sh within script2.sh?
You are sourcing a script, not running it. Therefore, you are looking for BASH_SOURCE.
$ cat test.sh
echo $BASH_SOURCE
$ . ./test.sh
./test.sh
Update:
Some people posted that BASH_SOURCE is indeed an array and, while this is actually true, I don't think you need to use all the syntax boilerplate because. "$BASH_SOURCE" (yes, you should quote your variables) will return the first element of the array, exactly what you are looking for.
Said that, it would be useful to post and example of using BASH_SOURCE as an array so here it goes:
$ cat parent.sh
#!/bin/bash
. ./child.sh
$ cat child.sh
#!/bin/bash
. ./grandchild.sh
$ cat grandchild.sh
#/bin/bash
echo "BASH_SOURCE: $BASH_SOURCE"
echo "child : ${BASH_SOURCE[0]}"
echo "parent1 : ${BASH_SOURCE[1]}"
echo "parent2 : ${BASH_SOURCE[2]}"
$ ./parent.sh
BASH_SOURCE: ./grandchild.sh
child : ./grandchild.sh
parent1 : ./child.sh
parent2 : ./parent.sh

Failed to source ~/.bashrc from bash script

In my script, I try to source two files to fetch the variables.
But it failed to get the variables defined in ~/.bashrc.
OS: Ubuntu Desktop 20.04.2 LTS
$ cat debug.sh
#!/usr/bin/env bash
cat > ~/env.sh << EOF
VAR1="123"
EOF
echo "VAR2=456" >> ~/.bashrc
source ~/env.sh
source ~/.bashrc
set -u
echo ${VAR1}
echo ${VAR2}
$ ./debug.sh
123
./debug.sh: line 14: VAR2: unbound variable
In the ubuntu version, .bashrc will check whether it is running interactively, if it is not, it will do nothing. Non-interactive means you called it inside another shell, which you can just comment out the following lines in .bashrc.
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac

Can't run bash file inside ZSH

I've placed a bash file inside .zshrc and tried all different ways to run it every time I open a new terminal window or source .zshrc but no luck.
FYI: it was working fine on .bashrc
here is .zshrc script:
#Check if ampps is running
bash ~/ampps_runner.sh & disown
Different approach:
#Check if ampps is running
sh ~/ampps_runner.sh & disown
Another approach:
#Check if ampps is running
% ~/ampps_runner.sh & disown
All the above approaches didn't work (meaning it supposes to run an app named ampps but it doesn't in zsh.
Note: It was working fine before switching to zsh from bash. so it does not have permission or syntax problems.
Update: content of ampps_runner.sh
#! /usr/bin/env
echo "########################"
echo "Checking for ampps server to be running:"
check=$(pgrep -f "/usr/local/ampps" )
#[ -z "$check" ] && echo "Empty: Yes" || echo "Empty: No"
if [ -z "$check" ]; then
echo "It's not running!"
cd /usr/local/ampps
echo password | sudo -S ./Ampps
else
echo "It's running ..."
fi
(1) I believe ~/.ampps_runner.sh is a bash script, so, its first line should be
#!/bin/bash
or
#!/usr/bin/bash
not
#! /usr/bin/env
(2) Then, the call in zsh script (~/.zshrc) should be:
~/ampps_runner.sh
(3) Note: ~/.ampps_runner.sh should be executable. Change it to executable:
$ chmod +x ~/ampps_runner.sh
The easiest way to run bash temporarily from a zsh terminal is to
exec bash
or just
bash
Then you can run commands you previously could only run in bash. An example
help exec
To exit
exit
Now you are back in your original shell
If you want to know your default shell
echo $SHELL
or
set | grep SHELL=
If you want to reliably know your current shell
ps -p $$
Or if you want just the shell name you might use
ps -p $$ | awk "NR==2" | awk '{ print $4 }' | tr -d '-'
And you might just put that last one in a function for later, just know that it is only available if it was sourced in a current shell.
whichShell(){
local defaultShell=$(echo $SHELL | tr -d '/bin/')
echo "Default: $defaultShell"
local currentShell=$(ps -p $$ | awk "NR==2" | awk '{ print $4 }' | tr -d '-')
echo "Current: $currentShell"
}
Call the method to see your results
whichShell

Linux bash script: share variable among terminal windows

If I do this:
#!/bin/bash
gnome-terminal --window-with-profile=KGDB -x bash -c 'VAR1=$(tty);
echo $VAR1; bash'
echo $VAR1
How can I get the last line from this script to work? I.e., be able to access the value of $VAR1 (stored on the new terminal window) from the original one? Currently, while the first echo is working, the last one only outputs an empty line.
The short version is that you can't share the variable. There's no shared channel for that.
You can write it to a file/pipe/etc. and then read from it though.
Something like the following should do what you want:
#!/bin/bash
if _file=$(mktemp -q); then
gnome-terminal --window-with-profile=KGDB -x bash -c 'VAR1=$(tty); echo "$VAR1"; declare -p VAR1 > '\'"$_file"\''; bash'
cat "$_file"
. "$_file"
echo "$VAR1"
fi

Resources