alias not recognized if alias command is piped to bash [duplicate] - bash

This question already has answers here:
bash: unable to set and use alias in the same line
(2 answers)
Closed 3 years ago.
I would like to get aliases to work in non-interactive bash. I run the following command :
bash -c "alias toto=ls; shopt -s expand_aliases; alias toto=ls; toto"
and I get the following :
bash: toto : commande not found
What am I doing wrong ?

From man bash:
Aliases are expanded when a command is
read, not when it is executed. Therefore, an alias definition
appearing on the same line as another command does not take
effect until the next line of input is read.
That means, even in an interactive shell,
alias toto=ls; toto
wouldn't work. There must be a line break between alias definition and call. So,
bash -c 'shopt -s expand_aliases; alias toto=ls
toto'
should work.

Related

bash script from docker does not work as expected if statement [duplicate]

This question already has answers here:
Difference between sh and Bash
(11 answers)
Pattern matching in UNIX Case statement
(1 answer)
Closed 1 year ago.
I am using this image which has bash v4.3.48 and curl v7.56.1:
https://hub.docker.com/r/bizongroup/alpine-curl-bash/tags?page=1&ordering=last_updated
Inside the docker I write the following script:
email_dest="iz#gmail.com}}"
suffix="#gmail.com"
dm_to=${email_dest%"$suffix"}
if [[ $email_dest == *"#users.noreply.github.com"* ]]
then
echo "Email address is no reply. Please fix your email preferences in Github"
elif [[ $email_dest == *$suffix* ]]
then
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello <#'"$dm_to"'>. '{{inputs.parameters.workflow_name}}' "}' https://hooks.slack.com/services/T01JNE5DXA7/B0246T84N75/hHDk7RUg2BWl2bYbPoN9r
else
echo "Email address is not of digibank domain!"
fi
If I run this script with bash command <script_name> it will work as expected (Run the curl command). But if I run it with sh command <script_name> it will not run the curl command:
/ # bash send-message.sh
ok/ #
/ # sh send-message.sh
Email address is not of digibank domain!
Any suggestion of what it could be? and what should be changed so it will work with sh?
That lies within the differences between bash and sh:
sh is POSIX compliant, whereas bash isn't (fully).
As a best practice you should always include a shebang:
#!/usr/bin/env bash
echo "this is going to run within bash"
With this you can now omit calling the script via bash myscript and just call it with ./myscript and it is always going to use bash (even if you are in a zsh, sh or whatever else).
However, if you truly want to have a script that runs with both sh and bash then you should rewrite your script to be plain sh compliant (i.e. POSIX).
TL;DR
Any suggestion of what it could be? and what should be changed so it will work with sh?
In your script you are using bash extensions such as [[ which is why it does not work with sh.
Checkout the links I posted above for more differences and how you can "convert" your bash script into a sh script.
The following site has a great summary on what to change in order to get your bash script working for dash which is an implementation of sh: http://mywiki.wooledge.org/Bashism
Furthermore, you can also check if any issues exist by using the following site: https://www.shellcheck.net/

Diffrence between bash script.sh and ./script.sh [duplicate]

This question already has answers here:
History command works in a terminal, but doesn't when written as a bash script
(3 answers)
Closed 2 years ago.
Suppose we have env.sh file that contains:
echo $(history | tail -n2 | head -n1) | sed 's/[0-9]* //' #looking for the last typed command
when executing this script with bash env.sh, the output will be empty:
but when we execute the script with ./env.sh, we get the last typed command:
I just want to know the diffrence between them
Notice that if we add #!/bin/bash at the beginning of the script, the ./env.sh will no longer output anything.
History is disabled by BASH in non-interactive shells by-default. If you want to enable it however, you can do so like this:
#!/bin/bash
echo $HISTFILE # will be empty in non-iteractive shell
HISTFILE=~/.bash_history # set it again
set -o history
# the command will work now
history
The reason this is done is to avoid cluttering the history by any commands being run by any shell scripts.
Adding hashbang (meaning the file is to be interpreted as a script by the program specified in your hashbang) to your script when being run via ./env.sh invokes your script using the binary /bin/bash i.e. run via bash, thus again printing no history.

How to use tee when using sudo [duplicate]

This question already has answers here:
How do I use sudo to redirect output to a location I don't have permission to write to? [closed]
(15 answers)
Closed 1 year ago.
UBuntu 16.04
Bash 4.4
In 4-bash-update.sh line 158:
cd "$drive00" && sudo -H -u myuser bash -c "timeout 2s ./binaryfile -gentoken" > "${save_log_dir}"/update-"${now}".log;
^-- SC2024: sudo doesn't affect redirects. Use ..| sudo tee file
I tried a few times and each time my file gets eaten.
You don't need to use tee, just put the redirection inside the command that's executed with bash -c:
sudo -H -u myuser bash -c 'timeout 2s ./binaryfile -gentoken > "$1"' _ "${save_log_dir}/update-${now}.log"
If you redirect outside, your original shell is trying to open the file, but it doesn't have permission. Putting it inside the bash argument executes it in the target user's shell, with their permissions.
The _ in the command line is a dummy value for the $0 parameter of the shell. You need that placeholder to be able to supply the filename as $1.

bash script not reading alias in bashrc [duplicate]

This question already has answers here:
How to set an alias inside a bash shell script so that is it visible from the outside? [duplicate]
(4 answers)
How to use aliases defined in .bashrc in other scripts?
(6 answers)
Closed 2 years ago.
I have created an alias in the .bashrc file:
alias java='java -Xmx1200m'
This alias works when I run a java command from my shell directly.
However, when the java command is inside a bash script (script.sh), this alias does not get activated. How do I ensure that the aliases in .bashrc file are accepted in a bash script ??
Alias are not expanded in non-interactive shells.
The only way to make an alias is to source the target script with the one which contains the alias.
$ source .bashrc
$ . custom_script.sh
Quoting from the bash manual:
Aliases are not expanded when the shell is not interactive, unless the
expand_aliases shell option is set using shopt (see The Shopt
Builtin).
Saying the following in your script should make it work:
shopt -s expand_aliases
Aliases are limited to the shell and do not work in executed shell scripts. You are better off creating a variable.
The simplest answer is to do the 2 important things or it wont' work. In your other script, do the following: -i for interactive mode, and shopt part as mentioned below.
#!/bin/bash -i
# Expand aliases defined in the shell ~/.bashrc
shopt -s expand_aliases
After this, your aliases that you have defined in ~/.bashrc they will be available in your shell script (giga.sh or any.sh) and to any function or child shell within such script.
If you don't do that, you'll get an error:
your_cool_alias: command not found
You can run your script under bash bash in interactive mode; add -i to bash command line, like this script. Now you can use your aliases.
#!/bin/bash -i
alias lsd='ls -al | grep ^d'
lsd

using alias in shell script? [duplicate]

This question already has answers here:
How to use aliases defined in .bashrc in other scripts?
(6 answers)
Closed 2 years ago.
My alias defined in a sample shell script is not working. And I am new to Linux Shell Scripting.
Below is the sample shell file
#!/bin/sh
echo "Setting Sample aliases ..."
alias xyz="cd /home/usr/src/xyz"
echo "Setting done ..."
On executing this script, I can see the echo messages. But if I execute the alias command, I see the below error
xyz: command not found
am I missing something ?
source your script, don't execute it like ./foo.sh or sh foo.sh
If you execute your script like that, it is running in sub-shell, not your current.
source foo.sh
would work for you.
You need to set a specific option to do so, expand_aliases:
shopt -s expand_aliases
Example:
# With option
$ cat a
#!/bin/bash
shopt -s expand_aliases
alias a="echo b"
type a
a
$ ./a
# a is aliased to 'echo b'
b
# Without option
$ cat a
#!/bin/bash
alias a="echo b"
type a
a
$ ./a
./a: line 3: type: a: not found
./a: line 4: a: command not found
reference: https://unix.stackexchange.com/a/1498/27031 and https://askubuntu.com/a/98786/127746
sourcing the script source script.sh
./script.sh will be executed in a sub-shell and the changes made apply only the to sub-shell. Once the command terminates, the sub-shell goes and so do the changes.
OR
HACK: Simply run following command on shell and then execute the script.
alias xyz="cd /home/usr/src/xyz"
./script.sh
To unalias use following on shell prompt
unalias xyz
If you execute it in a script, the alias will be over by the time the script finishes executing.
In case you want it to be permanent:
Your alias is well defined, but you have to store it in ~/.bashrc, not in a shell script.
Add it to that file and then source it with . .bashrc - it will load the file so that alias will be possible to use.
In case you want it to be used just in current session:
Just write it in your console prompt.
$ aa
The program 'aa' is currently not installed. ...
$
$ alias aa="echo hello"
$
$ aa
hello
$
Also: From Kent answer we can see that you can also source it by source your_file. In that case you do not need to use a shell script, just a normal file will make it.
You may use the below command.
shopt -s expand_aliases
source ~/.bashrc
eval $command
Your alias has to be in your .profile file not in your script if you are calling it on the prompt.
If you put an alias in your script then you have to call it within your script.
Source the file is the correct answer when trying to run a script that inside has an alias.
source yourscript.sh
Put your alias in a file call ~/.bash_aliases and then, on many distributions, it will get loaded automatically, no need to manually run the source command to load it.

Resources