I have an alias like alias cdpy="cd python" in my .bash_profile and I have sourced it. But I am still not able to use that in another shell script of mine, which is called pygitup.
I googled it and got some answers like adding shopt -s expand_aliases. I have added it to the pygitup but it still doesn't work. Am I using it wrong? This is how I use it:
# some code
shopt -s expand_aliases
cdpy
# some code
If you run pygitup from your environment with a leading "dot space", it will inherit your shell's configuration, including aliases.
A simple example with a bash script:
user#pc:~ $ alias e='echo alias is set'
user#pc:~ $ e
alias is set
user#pc:~ $ vim pygitup.sh
user#pc:~ $ cat pygitup.sh
#!/bin/bash
e
user#pc:~ $
user#pc:~ $ ./pygitup.sh
./pygitup.sh: line 2: e: command not found
user#pc:~ $
user#pc:~ $
user#pc:~ $ . ./pygitup.sh # <--- notice the leading dot
alias is set
user#pc:~ $
Aliases are not inherited by external commands, so there's no alias to expand. You'd have to source the file that defines the alias again in your script:
# some code
shopt -s expand_aliases
source ~/.bash_profile
cdpy
# some code
Related
I know writing
source ~/.bashrc
shopt -s expand_aliases
in a bash script allows to use aliases defined in .bashrc file.
However, I have so many bash scripts, and I cannot change all those scripts.
Is there a way to let my aliases used in all my scripts, with setting env or something?
Put the code that enables aliases and sources .bashrc to another file, assign its path to BASH_ENV, and export BASH_ENV.
$ cat .bashrc
alias dt=date
$ cat my_env.sh
shopt -s expand_aliases
source ~/.bashrc
$ cat my_script
#!/bin/bash
dt
$ export BASH_ENV=my_env.sh
$ ./my_script
Tue Mar 30 07:57:50 +03 2021
in my ~/.bashrc, for git I have this alias
alias g='git'
how I can use the autocompletion of git with my alias g ?
Add the following line to your .bashrc file:
complete -F XXX g
where XXX should be replaced by the value following -F in the output of the following command:
complete -p git
(It is likely, but not guaranteed, that this will be _git.)
In my cygwin's .bashrc I have the following two aliases:
alias dospath='cygpath -w `pwd`'
alias dospathcp='dospath > /dev/clipboard'
The first one is supposed to print the dos (or windows) path of the directory in which it is executed. This one works as expected.
The second alias is then supposed to redirect the output of dospath into /dev/clipboard so that I can paste it in windows applications. This one does not work. When I type dospathcp in bash, it just empties /dev/clipboard (and the clipbaord itself).
Try as follows:
alias dospath='cygpath -w $PWD'
alias dospathcp='dospath > /dev/clipboard'
This produces following output in my CYGWIN_NT-6.1-WOW64 CC 1.7.25(0.270/5/3) 2013-08-31 20:39 i686 Cygwin
$ alias dospath='cygpath -w $PWD'
$ cd /home/somedir
$ dospath
W:\cygwin\home\somedir
$ cd /home/anotherdir
$ dospath
W:\cygwin\home\anotherdir
$ alias dospathcp='dospath > /dev/clipboard'
$ cd /home/somedir
$ dospathcp
$ cat /dev/clipboard
W:\cygwin\home\somedir
$ cd /home/anotherdir
$ dospathcp
$ cat /dev/clipboard
W:\cygwin\home\anotherdir
See http://ss64.com/bash/alias.html
The first word of the replacement text is tested for aliases, but a
word that is identical to an alias being expanded is not expanded a
second time. This means that one may alias ls to "ls -F", for
instance, and Bash does not try to recursively expand the replacement
text.
I have configured a Jenkins job to source a bash script that sources another bash script which adds an alias to the .bashrc of its user and sources the .bashrc itself, and then original script tries to use that alias (set by the second). However, it cannot seem to find the alias it has just created. I am not using any scripting plugins aside from using a "Send files or execute commands over SSH" build step to source the script.
The job does this:
source ./test_script.sh
test_script.sh looks like this:
echo "In test_script.sh"
echo $USER
echo $HOME
source ./setup_env.sh
echo "\nBack in test_script.sh"
alias foo
foo
And finally, setup_env.sh looks like this:
echo "\nIn setup_env.sh"
echo "alias foo=\"echo foobar\"" >> $HOME/.bashrc
source $HOME/.bashrc 2>/dev/null
cat $HOME/.bashrc
The output I receive from the Jenkins job looks like this:
In test_script.sh
my_user
/home/my_user
\nIn setup_env.sh
...all of my bashrc...
alias foo="echo foo"
\nBack in test_script.sh
alias foo='echo foo'
./test_script.sh: line 7: foo: command not found
I don't understand why this is happening, when I can happily run it myself on the command-line and watch it succeed. Why can't Jenkins use the new alias, when it can obviously find it (as demonstrated by the output of the alias foo command)?
For anyone else who's having this problem, you may need to set the expand_aliases shell option, which seems to be off by default with Jenkins:
shopt expand_aliases # check if it's on
shopt -s expand_aliases # set expand_aliases option to true
shopt expand_aliases # it should be on now
# test with a simple alias, should print 1
alias x="python -c 'print 1'"
x
The \n that is showing in the output of your echo commands
suggest this is not running under bash, as you may be expecting.
Please check the setting of your jenkins user
(or any other user that you run Jenkins with) -
especially the setting of the default shell.
To test this, add one of those lines at the beginning of your script:
env
or
env | grep -i shell
Should also consider making sure your scripts run under the correct shell,
by adding the "shebang" line as the first line in each script.
In the case of 'bash', for example, you should add the following first line:
#!/bin/bash
(it is not a comment, despite what the auto-syntax-highlighter may think...)
$0 expands to the name of the shell script.
$ cat ./sample-script
#!/bin/bash
echo $0
$ chmod 700 ./sample-script
$ ./sample-script
./sample-script
If the shell script is invoked via a symbolic link, $0 expands to its name:
$ ln -s ./sample-script symlinked-script
$ ./symlinked-script
./symlinked-script
How could I get the name of an alias? Here `$0' expands again to the filename:
$ alias aliased-script=./sample-script
$ aliased-script
./sample-script
Aliases are pretty dumb, according to the man page
...Aliases are expanded when a command is read, not when it is executed...
so since bash is basically just replacing a string with another string and then executing it, there's no way for the command to know what was expanded in the alias.
I imagine you already know this, but for the record the answer is: you need cooperation by the code implementing the alias.
alternate_name () {
MY_ALIAS_WAS=alternate_name real_name "$#"
}
or, if you really want to use the superseded alias syntax:
alias alternate_name="MY_ALIAS_WAS=alternate_name real_name"
...and then...
$ cat ~/bin/real_name
#!/bin/sh
echo $0, I was $MY_ALIAS_WAS, "$#"
bash does not make this available. This is why symlinks are used to invoke multiplex commands, and not aliases.