Using alias in bash function - bash

I have defined an alias like so:
alias X="path/to/program"
and I have a function defined like this:
doX() { X -flag "$1"; }
I put these in my .bashrc file, and when I open bash, I get a syntax error near unexpected token '-flag'. At this point, the alias has been set, but the function has not, due to this error. If I run
doX() { X -flag "$1"; }
at this point, it works. I have tried putting this into a file and sourcing it after I set the alias in the .bashrc file, but it is giving me the same results.
How can I fix this? Is there a way to define the alias AND the function in the .bashrc so that they are both set when I open bash?

Aliases are not usually available in scripts. If you want to have a function use an alias, consider making the alias itself a function:
X() { path/to/program "$#"; }
doX() { X -flag "$1"; }

Related

Variable in bash script exported in function

I have a function in a script, in which I would like to expand a variable. How do I do it?
eg:
set_function.sh:
function test_funct {some_binary --configfile="$1"/folder/; }
export -f test_funct
I would like it so that if I call:
./set_function.sh /some/path/here
the passed variable /some/path/here gets expanded so that if I then call
test_funct --some-other-flag
I don't get:
some_binary --configfile=--some-other-flag/some_path/
but rather
some_binary --configfile=/some/path/here/folder/ --some-other-flag
Seems like you need to use variables, like this:
test_func() {
some_binary --config $CONFIG_PATH/folder/ "$#"
}
and call it like
CONFIG_PATH=~/config1 test_func --verbose
export CONFIG_PATH=~/config2
test_func --quiet
Also note that you cannot export things upwards, i.e. you cannot call set_function.sh so that test_func be exported to the calling shell. You need . set_function.sh or equally source set_function.sh instead.

How to change current directory using the command_not_found_handle in Bash?

In my .bashrc file, I have a function
changeDirectory()
{
cd "/home/bin"
}
If I'm in /home and I type changeDirectory on the command line, the current directory becomes /home/bin
If this function is called from other functions, it also works to change the current directory.
handler()
{
changeDirectory
}
If I type handler in the command line, it changes my current directory to /home/bin
However, if I call changeDirectory from this function:
command_not_found_handle()
{
changeDirectory
echo "$PWD"
}
When I type a command this isn't found, and this function is called, it will print /home/bin, but when I type pwd on the command line, I'm still in /home
The command_not_found_handler function seems to behave differently than normal functions. Is there a work around to be able to change my current directory?
A slight twist on #Cyrus' answer, using a temporary file instead of exit code.
command_not_found_handle () { touch $HOME/.changedirectory.$$; }
PROMPT_COMMAND='rm $HOME/.changedirectory.$$ 2>/dev/null && changeDirectory'

Difference when executing bash function in an alias

I have a function in my .bash_profile for printing text some pre-written text and copying it to the clipboard.
copyandprint () {
s='\\033[1;32m' #strong
n='\\033[0m' #normal
printf -- "printf -- '$1' | pbcopy;" #pbcopy copies to clipboard in macOS
printf -- "echo -e copied '${s}$1${n}' to clipboard"
}
I use this to alias things I keep wanting to paste into other applications, like static IDs, or just silly things that are difficult to type quickly on a keyboard.
alias shrug=$( copyandprint '¯\_(ツ)_/¯')
But when I wanted to use it with text generated at the time I use the alias, I can't just call it in the alias definition; the alias needs to call it.
alias copydate=$( copyandprint "$(date)" )
The value is generated when the script is run, not when the alias is used.
Through pretty much sheer trial and error, I was able to make a modified version of the function that does what I wanted:
copyandprint_live () {
s='\\033[1;32m' #strong
n='\\033[0m' #normal
printf -- "$1" | pbcopy
printf -- "echo -e copied ${s}$1${n} to clipboard"
}
alias copydate_live="\$( copyandprint_live \"\$(date)\" )"
The date is generated at the time the alias is used, rather than at the time the script is executed.
But when I use that function the way I used the other one, it fails:
alias shrug_2=$( copyandprint_live '¯\_(ツ)_/¯')
$ shrug_2
#=> -bash: syntax error near unexpected token `ツ'
And I tried putting double quotes, but that didn't work
alias shrug_3=$( copyandprint_live '"¯\_(ツ)_/¯"')
$ shrug_3
#=> copied 033[1
#=> -bash: 32m¯\_(ツ)_/¯033[0m: No such file or directory
My question is, what's going on here? Why do they need to be so different?
Dispensing with the aliases and using functions makes this a lot easier.
copyandprint () {
printf '%s' "$1" | pbcopy
printf 'copied \033[1;32m%s\033[0m to clipboard\n' "$1"
}
shrug () {
copyandprint '¯\_(ツ)_/¯'
}
copydate () {
copyandprint "$(date)"
}
Functions work alike any other command:
$ foo () { echo hi; }
$ foo
hi
You're calling the function when you define the aliases, not when you use them. You need to put the alias definition in single quotes to prevent $(...) from executing the command at that time.
alias shrug='$( copyandprint "¯\_(ツ)_/¯")'

Difference between bash (shell) function syntaxes? [duplicate]

For example:
Bash-Prog-Intro-HOWTO
function foo() {}
I make search queries in info bash and look in releted chapters of POSIX for function keyword but nothing found.
What is function keyword used in some bash scripts? Is that some deprecated syntax?
The function keyword is optional when defining a function in Bash, as documented in the manual:
Functions are declared using this syntax:
name () compound-command [ redirections ]
or
function name [()] compound-command [ redirections ]
The first form of the syntax is generally preferred because it's compatible with Bourne/Korn/POSIX scripts and so more portable.
That said, sometimes you might want to use the function keyword to prevent Bash aliases from colliding with your function's name. Consider this example:
$ alias foo="echo hi"
$ foo() { :; }
bash: syntax error near unexpected token `('
Here, 'foo' is replaced by the text of the alias of the same name because it's the first word of the command. With function the alias is not expanded:
$ function foo() { :; }
The function keyword is necessary in rare cases when the function name is also an alias. Without it, Bash expands the alias before parsing the function definition -- probably not what you want:
alias mycd=cd
mycd() { cd; ls; } # Alias expansion turns this into cd() { cd; ls; }
mycd # Fails. bash: mycd: command not found
cd # Uh oh, infinite recursion.
With the function keyword, things work as intended:
alias mycd=cd
function mycd() { cd; ls; } # Defines a function named mycd, as expected.
cd # OK, goes to $HOME.
mycd # OK, goes to $HOME.
\mycd # OK, goes to $HOME, lists directory contents.
The reserved word function is optional. See the section 'Shell Function Definitions' in the bash man page.

Passing argument to alias in bash [duplicate]

This question already has answers here:
Make a Bash alias that takes a parameter?
(24 answers)
Closed 5 years ago.
Is it possible to do the following:
I want to run the following:
mongodb bin/mongod
In my bash_profile I have
alias = "./path/to/mongodb/$1"
An alias will expand to the string it represents. Anything after the alias will appear after its expansion without needing to be or able to be passed as explicit arguments (e.g. $1).
$ alias foo='/path/to/bar'
$ foo some args
will get expanded to
$ /path/to/bar some args
If you want to use explicit arguments, you'll need to use a function
$ foo () { /path/to/bar "$#" fixed args; }
$ foo abc 123
will be executed as if you had done
$ /path/to/bar abc 123 fixed args
To undefine an alias:
unalias foo
To undefine a function:
unset -f foo
To see the type and definition (for each defined alias, keyword, function, builtin or executable file):
type -a foo
Or type only (for the highest precedence occurrence):
type -t foo
to use parameters in aliases, i use this method:
alias myalias='function __myalias() { echo "Hello $*"; unset -f __myalias; }; __myalias'
its a self-destructive function wrapped in an alias, so it pretty much is the best of both worlds, and doesnt take up an extra line(s) in your definitions... which i hate, oh yeah and if you need that return value, you'll have to store it before calling unset, and then return the value using the "return" keyword in that self destructive function there:
alias myalias='function __myalias() { echo "Hello $*"; myresult=$?; unset -f __myalias; return $myresult; }; __myalias'
so..
you could, if you need to have that variable in there
alias mongodb='function __mongodb() { ./path/to/mongodb/$1; unset -f __mongodb; }; __mongodb'
of course...
alias mongodb='./path/to/mongodb/'
would actually do the same thing without the need for parameters, but like i said, if you wanted or needed them for some reason (for example, you needed $2 instead of $1), you would need to use a wrapper like that. If it is bigger than one line you might consider just writing a function outright since it would become more of an eyesore as it grew larger. Functions are great since you get all the perks that functions give (see completion, traps, bind, etc for the goodies that functions can provide, in the bash manpage).
I hope that helps you out :)
Usually when I want to pass arguments to an alias in Bash, I use a combination of an alias and a function like this, for instance:
function __t2d {
if [ "$1x" != 'x' ]; then
date -d "#$1"
fi
}
alias t2d='__t2d'
This is the solution which can avoid using function:
alias addone='{ num=$(cat -); echo "input: $num"; echo "result:$(($num+1))"; }<<<'
test result
addone 200
input: 200
result:201
In csh (as opposed to bash) you can do exactly what you want.
alias print 'lpr \!^ -Pps5'
print memo.txt
The notation \!^ causes the argument to be inserted in the command at this point.
The ! character is preceeded by a \ to prevent it being interpreted as a history command.
You can also pass multiple arguments:
alias print 'lpr \!* -Pps5'
print part1.ps glossary.ps figure.ps
(Examples taken from http://unixhelp.ed.ac.uk/shell/alias_csh2.1.html .)
To simplify leed25d's answer, use a combination of an alias and a function. For example:
function __GetIt {
cp ./path/to/stuff/$* .
}
alias GetIt='__GetIt'

Resources