[In my .bashrc]
Basically I try to make an alias:
alias e='su -c'
But when I write in a terminal:
~$ e ls -goFha /root
I (obviously) get the error:
su: group oFha does not exist
If $str were replaced by the rest of the command, the herebelow code would work:
alias e='su -c "$str"'
But alias don't work this way. Therefore, I thought to a function.
Replacing $str by the whole argument string, it could be something like:
e () {
"su -c '$str'"
}
How to get the whole argument string in a function?
How would you write my function?
Thanks
Here is another solution:
e() {
su -c "$*"
}
You can try this:
e () {
CMD="$#"
su -c "$CMD"
}
Related
Note this is sourced, so this is not a shell script.
I am not asking for how to enable alias in noninteractive shell. I did this: shopt -s expand_aliases.
The Bash version is 5.1.4.
How to recreate:
Create a file named "p":
linky(){
comdll="cat"
shopt -s expand_aliases
alias modavar="$comdll"
echo "$argin" | modavar #| getlinks "$argin" | sort -u
}
Then run
echo "source p ; linky https://duckduckgo.com" | bash --norc
Expected output:
https://duckduckgo.com
Actual output:
p: line 5: modavar: command not found
When I run this once it give me
linky(){ alias jkl=echo\ hel; jkl; }
linky
bash: jkl: command not found
But if I do this,
linky(){ alias jkl=echo\ hel; jkl; }
linky
linky(){ alias jkl=echo\ hel; jkl; }
linky
It gives me
hel
What is happening?
You can't define the alias inside a function and use it there. Consider these examples:
alias foo=cat
ffoo() {
echo abc|foo
}
fbar() {
alias bar=cat
echo abc|bar
}
ffoo #->prints abc
fbar #->prints command not found
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 "¯\_(ツ)_/¯")'
I'd like to get the function name from within the function, for logging purposes.
KornShell (ksh) function:
foo ()
{
echo "get_function_name some useful output"
}
Is there anything similar to $0, which returns the script name within scripts, but which instead provides a function's name?
If you define the function with the function keyword, then $0 is the function name:
$ function foo {
> echo "$0"
> }
$ foo
foo
(Tested in pdksh.)
[...] what are the main pros/cons of using keyword function?
Main pro is that "typeset myvar=abc" inside the function is now a local variable, with no possible side effects outside the function. This makes KSH noticeably safer for large shell scripts. Main con is, perhaps, the non-POSIX syntax.
Use the ksh "function foo ..." form:
$ cat foo1
#!/bin/ksh
foo3() { echo "\$0=$0"; }
function foo2 { echo "\$0=$0"; }
foo2
foo3
$ ./foo1
$0=foo2
$0=./foo1
The function below seems to get its name in both Bash and ksh:
# ksh or bash
function foo {
local myname="${FUNCNAME[0]:-$0}"
echo "$myname"
}
# test
foo
# ...
In the bash manual section 3.7.4, it states
The environment for any simple command or function may be augmented
temporarily by prefixing it with parameter assignments, as described
in Shell Parameters [section 3.4].
And a trivial example of this is
MYVAR=MYVALUE mycommand
I have read section 3.4 and I still can't figure out how to specify multiple parameter assignments. Note that the statement in 3.7.4 is definitely plural, implying that it is possible.
The following does not seem to work:
MYVAR1=abc MYVAR2=xyz mycommand
I am using bash version 4.1, 23 December 2009.
It should work. That is acceptable syntax. Here's an example:
$ cat a
#!/bin/sh
echo $MYVAR1
echo $MYVAR2
$ ./a
$ MYVAR1=abc MYVAR2=xyz ./a
abc
xyz
$
UPDATE: Your updated example given in your answer will work if you precede the simple command with the variables as required:
mycommand () { echo MYVAR1=[$MYVAR1]; echo MYVAR2=[$MYVAR2]; }
for f in ~/*.txt ; do MYVAR1=abc MYVAR2=xyz mycommand; done
Oops, my example was over-simplified. This works fine:
mycommand () { echo MYVAR1=[$MYVAR1]; echo MYVAR2=[$MYVAR2]; }
MYVAR1=abc MYVAR2=xyz mycommand
but this does not:
mycommand () { echo MYVAR1=[$MYVAR1]; echo MYVAR2=[$MYVAR2]; }
MYVAR1=abc MYVAR2=xyz for f in ~/*.txt; do mycommand; done
and the key difference is this phrase:
for any simple command or function
A for command is a complex command, not "a simple command or function", according to section 3.2.
I've never seen that method used.
You could always just pass in regular parameters to the script.
Updating for new example:
This works in both situations:
> mycommand () { echo MYVAR1=[$1]; echo MYVAR2=[$2]; }
> mycommand a b
MYVAR1=[a]
MYVAR2=[b]
> for f in ~/file*.txt; do mycommand a b; done
MYVAR1=[a]
MYVAR2=[b]
MYVAR1=[a]
MYVAR2=[b]
I am trying to set an env variable which I can use to do relative directory chains. I am trying to do it the following way but cant get it to work. How do I do it?
alias sroot="export SROOT="$PWD""
alias drumit="cd $SROOT/abc/def/drumit"
If I type sroot, it takes the alias but when i type drumit, it gives me an error saying
bash: cd: /abc/def/drumit: No such file or directory
Looks like when the shell was launched it takes $SROOT as .
Appreciate any help.
Thanks
Your $PWD and $SROOT variables are being expanded at the time you define the aliases, not when you are using them. Put a \ in front of them to escape them while they are defined.
alias sroot="export SROOT="\$PWD""
alias drumit="cd \$SROOT/abc/def/drumit"
When you initially set the alias, it expands $PWD instead of keeping it as the variable form. Try using function instead like this:
$ function sroot {
> export SROOT="$PWD"
> }
$ export -f sroot
$ function drumit {
> cd $SROOT/cron
> }
$ export -f drumit
$ declare -f sroot
sroot()
{
export SROOT="$PWD"
}
$ declare -f drumit
drumit ()
{
cd $SROOT/abc/def/drumit
}
This is what is currently happening when you alias like in your question (variable expanding):
$ alias sroot="export SROOT="$PWD""
$ alias drumit="cd $SROOT/abc/def/drumit"
$ alias
alias SROOT='/home/jon'
alias drumit='cd /home/jon/abc/def/drumit'
alias sroot='export SROOT=/home/jon'
Escaping would work too:
$ alias sroot="export SROOT="\$PWD""
$ alias drumit="cd \$SROOT/abc/def/drumit"
$ alias
alias drumit='cd $SROOT/abc/def/drumit'
alias sroot='export SROOT=$PWD'