bash script not reading alias in bashrc [duplicate] - bash

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

Related

bash alias cp='cp -i' not work as expectation in script

#!/bin/bash
alias cp='cp -i'
alias # this line output: "alias cp='cp -i'"
touch /tmp/{a,b}.txt
cp /tmp/a.txt /tmp/b.txt # this line doesn't work as my expectation
I expect it will show prompt at end, like this: "cp: overwrite ‘/tmp/b.txt’?"
It is because bash script is run in non-interactive mode. Try:
#!/bin/bash -i
or
shopt -s expand_aliases
Aliases are not expanded when the shell is not interactive, unless the
expand_aliases shell option is set using shopt.
See asnwers to: How to run an alias in a shell script?
Alternatively, you can use shell functions instead of aliases. Check answer to: In Bash, when to alias, when to script, and when to write a function?

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.

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

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.

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.

Difference in bash printf output between run script and source script

I can't seem to find the difference between a script run two different ways.
Here's the script (named test.sh):
#! /bin/bash
printf "%b\n" "\u5A"
When the script is sourced:
. test.sh
> Z ## Result I want ##
When the script is run:
./test.sh
> \u5A ## Result I get ##
I want the run script to give the results of the sourced script... what setting do I need to set/change?
You are probably getting different versions of printf; the script you are sourcing from is probably a /bin/sh script, not a Bash script proper?
Shouldn't you be using \x instead of \u? printf "%b\n" "\x5A" works fine in both cases for me.
(Totally different idea here, so I'm posting it as another answer.)
Try running these at the command line:
builtin printf "%b\n" "\u5A"
/usr/bin/env printf "%b\n" "\u5A"
printf is both a shell builtin and an executable, and you may be getting different ones depending on whether you source or run the script. To find out, insert this in the script and run it each way:
type printf
While you're at it, you may as well insert this line too:
echo $SHELL
That will reveal if you're getting different shells, per tripleee.
HAHA!!! I finally traced down the problem! Read ahead if interested (leave the page if not).
These are the only command that will translate \u properly:
. ./test.sh ## Sourcing the script, hash-bang = #! /bin/sh
. ./test.bash ## Sourcing the script, hash-bang = #! /bin/bash
./test ## Running the script with no hash-bang
All of the following produce identical results in that they do NOT translate \u:
./test.sh ## Script is run from an interactive shell but in a non-interactive shell
## test.sh has first line: #! /bin/sh
/bin/sh -c "./test.sh" ## Running the script in a non-interactive sh shell
/bin/sh -lc "./test.sh" ## Running the script in a non-interactive, login sh shell
/bin/sh -c ". ./test.sh" ## Sourcing the file in a non-interactive sh shell
/bin/sh -lc ". ./test.sh" ## Sourcing the file in a non-interactive, login sh shell
## test.bash has first line: #! /bin/bash
/bin/bash -c "./test.bash" ## Running the script in a non-interactive bash shell
/bin/bash -lc "./test.bash" ## Running the script in a non-interactive, login bash shell
/bin/bash -c ". ./test.bash" ## Sourcing the file in a non-interactive bash shell
/bin/bash -lc ". ./test.bash" ## Sourcing the file in a non-interactive, login bash shell
## And from ***tripleee*** (thanks btw):
/bin/sh --norc; . ./test.sh ## Sourcing from an interactive sh shell without the ~/.bashrc file read
/bin/bash --norc; . ./test.bash ## Sourcing from an interactive bash shell without the ~/.bashrc file read
The only way to get proper translation is to run the script without a hash-bang... and I finally figured out why! Without a hash-bang my system chooses the default shell, which btw is NOT /bin/bash... it turns out to be /opt/local/bin/bash... two different versions of bash!
Finally, I removed the OSX /bin/bash [v3.2.48(1)] and replaced it with the MacPorts /opt/local/bin/bash [v4.2.10(2)] and now running the script works! It actually solved about 10-15 other problems I've had (like ${var,,}, read sN1 char, complete -EC "echo ' '", and a host of other commands I have scattered throughout my scripts, ~/.bashrc amd ~/.profile). Honestly, I really should have noticed when my scripts using associative arrays suddenly crapped out on me... how stupid can I get!?
I've been using bash v4 for a looong time now, and my Lion upgrade went and down-graded bash back to v3 (get with the program Apple!)... ugh, I feel so ashamed! Everyone still using bash v3, upgrade!! bash v4 is has many, many beautiful upgrades over version 3. Type bash --version to see what version you are running. One advantage is now bash can translate \uHEX into Unicode!
Try removing the space in the first line, I seem to recall that can cause problems. Offhand I'd guess that because of that space, you're not getting bash, but sh.
Glad you solved it. Still, you might be looking for a portable solution.
Assuming you are always using the same formatting string, we can just discard it, and use something like this;
printf () {
# Discard format string
shift
perl -CSD -le '
print map { s/^\\u//; chr(hex($_)) } #ARGV' "$#"
}
Edit to add: You would simply add this function definition at the beginning of your existing script, overriding the builtin printf. Obviously, if you also use printf for other stuff, this special-purpose replacement isn't good enough.
You could rename the function to uprintf or something, still. It merely translates a sequence of hex codes to the corresponding Unicode characters, discarding any \u prefix.

Resources