Nathan Hinchey
Nathan Hinchey

Reputation: 1201

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 '¯\_(ツ)_/¯')

$ shrug #=> copied ¯_(ツ)_/¯ to clipboard

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 time is from when the script was first executed, not when the alias was used

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)\" )"

date generated at time alias is used

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?

Upvotes: 2

Views: 1626

Answers (2)

chepner
chepner

Reputation: 532053

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

Upvotes: 3

Barmar
Barmar

Reputation: 782105

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 "¯\_(ツ)_/¯")'

Upvotes: 2

Related Questions