How can you use multiple argv elements in an alias using tcsh? - unix

I'm making an alias to just rename a file. I have the following alias:
alias change 'mv argv[1] argv[2]'
I have a file in my directory called calendar. When I enter
change calendar new_cal
I want the filename to change to new_cal. Instead, it returns
mv: No match.

This will work:
alias change 'mv \!:1 \!:2'
$argv gets you the arguments passed to the script, while \!:1 and \!:2 will get you the first and second arguments passed to this command.
Also see Unix tcsh - alias using command line argument $1 versus \!:1

Related

zsh using a variable in a command within a function

In .zsh, in my .zshrc file I'd like to set up a function to cd to a directory I input, but using an existing variable to write the common ~/path/to/parent/directory/$input
I've been unable to find out what the correct syntax is for this particular usage. For example, I want to enter
goto mydir
and execute a cd to ~/path/to/parent/directory/mydir
But I get an error: gt:cd:3 no such file or directory ~/path/to/parent/directory/mydir even though that directory exists.
This is the variable declaration and function I am trying:
export SITESPATH="~/path/to/parent/directory"
function gt(){
echo "your site name is $#"
echo "SITESPATH: " $SITESPATH "\n"
cd $SITESPATH/$#
}
It makes no difference if I use the above, without quotes, or "cd $SITESPATH/$#" with quotes.
I don't see the point in using $# in your function, since you expect only one argument. $1 would be sufficient.
The problem is in the tilde which is contained in your variable SITEPATH. You need to have it expanded. You can either do it by writing
export SITESPATH=~/path/to/parent/directory
when you define the variable, or inside your function by doing a
cd ${~SITESPATH)/$1
A third possibility is to turn on glob_subst in your shell:
setopt glob_subst
In this case, you can keep your current definition of $SITESPATH, and tilde-substitution will happen automatically.

zsh temporarily disable alias within a function

I feel that zsh will expand aliases even it is called within a function, for example
alias abc='echo abc'
function fabc(){abc}
Is it possible to disable alias expansion in this function?
One more related question: Is it possible to disable alias expansion in the whole interactive shell?
You can disable a particular alias with
unalias abc
or all aliases with
unalias -a
Another solution is to force a command not to use an alias with a backslash
\abc
The problem is more difficult when used in a function... It seems from here, you cannot define or undefine your aliases in a function.
Aliases are expanded when a function definition is read, not when the
function is executed, because a function definition is itself a
compound command.
So you may want to do something like
alias abc='echo abc'
myaliases=$(alias -L)
unalias -a
function fabc(){
abc
}
eval $myaliases; unset myaliases
fabc
abc

Zsh not recognizing alias from within function

Here's my .zshrc:
alias inst="adb install -r -d"
notify() {
start=$(date +%s)
"$#"
notify-send "\"$(echo $#)\" took $(($(date +%s) - start)) seconds to finish"
}
When I run the command notify inst app.apk, I get an error:
notify:2: command not found: inst
0.00s user 0.00s system 0% cpu 0.001 total
Can anyone shed some light on why this doesn't work, and hopefully a way to make it work?
When the shell processes commands, among other things (e.g. PATH search) it will check to see if the first token/argument (whitespace delimited) belongs to an alias loaded in the current environment. If the alias you are trying to substitute is not the first token, the substitution will not happen. If your alias happens to not be the name of an executable on the PATH or current directory, the error will propagate back up to a command not found.
Since your question is about the Z Shell, zsh actually provides a lesser-known feature called global aliasing. If an alias is declared with the -g flag, zsh will make the appropriate substitution for not only the first token, but any token, regardless of order.
alias -g inst="adb install -r -d" should do the trick.
Keep in mind that this is a zsh only feature for portability reasons, and make sure that whatever script your writing has a shebang line that invokes the zsh shell: #!/usr/bin/env zsh
I would also recommend to not use zsh global aliasing in important or production scripts. For personal use, it is perfectly fine.
Don't use alias for scripting
First, according to the advanced bash scripting guide:
In a script, aliases have very limited usefulness.
So you may consider not using alias but a function for instance (still from the same page, 2 paragraph lower):
Almost invariably, whatever we would like an alias to do could be accomplished much more effectively with a function.
A hacky solution
If this is for a quick script for yourself using aliases you have in your .zshrc, there is still a way out.
alias foo='echo hello'
bar() {
`alias "$#" | cut -d\' -f2`
}
bar foo # => hello
Alias replacement
from alias man page:
The first word of each simple command, if unquoted, is checked to see if it has an alias. If so, that word is replaced by the text of the alias. The alias name and the replacement text can contain any valid shell input, including shell metacharacters, with the exception that the alias name can not contain `='.
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 can alias ls to "ls -F", for instance, and Bash does not try to recursively expand the replacement text.
Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt .
The rules concerning the definition and use of aliases are somewhat confusing. Bash always reads at least one complete line of input before executing any of the commands on that line. 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. The commands following the alias definition on that line are not affected by the new alias. This behavior is also an issue when functions are executed. Aliases are expanded when a function definition is read, not when the function is executed, because a function definition is itself a compound command. As a consequence, aliases defined in a function are not available until after that function is executed. To be safe, always put alias definitions on a separate line, and do not use alias in compound commands.

Zsh expand alias to result of function as string

Really quirky title, I know.
Basically, I have this:
alias vv="xclip -selection clipboard -o"
which prints out anything in my clipboard, such as a repository location in ssh-form (git#github.username/repname.git).
Now I'd like to:
git clone vv
I tried several variations of the above, such as trying various switches on the alias, or using different expansions, but with no luck.
Any suggestions?
Global alias might do it... actually it does it:
alias -g vv="$(date)" # replace 'date' with your command of choice
Notice:
it is a global alias, so it works anywhere in the command line (not just the beginning)
$(...) will do command substitution and expand it as a variable, see man zshexpn and search for $(...). By default zsh will not break the results using white-spaces.
[...]
I initially wrote a suggestion to create a (zsh) widget to insert the clipboard into the command line with a given key combination, then I realized that you would just likely hit "Ctrl-Shift-V" or something... :-S
[...]
FYI, this is how you would do this using a zsh widget:
that inserts the clipboard content on the command line, and binding it to some key, as it would allow you to see what you are doing before hitting enter. Place the following into your $fpath, inside a file called insert-clipboard (needs to be loaded with KSH_AUTOLOAD set)
#! /bin/zsh
## Inserts the output of the command into the cmd line buffer
zmodload -i zsh/parameter
insert-clipboard() {
LBUFFER+="$(date)" # REPLACE date BY YOUR COMMAND!
}
At your .zshrc
autoload insert-clipboard # as written, it needs KSH_AUTOLOAD set....
zle -N insert-clipboard
bindkey '^Xu' insert-clipboard # pick a key combination you like...

Get the `pwd` in an `alias`?

Is there a way I can get the pwd in an alias in my .zshrc file? I'm trying to do something like the following:
alias cleanup="rm -Rf `pwd`/{foo,bar,baz}"
This worked fine in bash; pwd is always the directory I've cd'd into, however in zsh it seems that it's evaluated when the .zshrc file is first loaded and always stays as my home directory. I've tested using with a really simple alias setup, but it never changes.
How can I have this change, so that calling the alias from a subdirectory always evaluates as that subdir?
EDIT: not sure if this will help, but I'm using zsh via oh-my-zsh on the mac.
When your .zshrc is loaded, the alias command is evaluated. The command consists of two words: a command name (the builtin alias), and one argument, which is the result of expanding cleanup="rm -Rf `pwd`/{foo,bar,baz}". Since backquotes are interpolated between double quotes, this argument expands to cleanup=rm -Rf /home/unpluggd/{foo,bar,baz} (that's a single shell word) where /home/unpluggd is the current directory at that time.
If you want to avoid interpolation at the time the command is defined, use single quotes instead. This is almost always what you want for aliases.
alias cleanup='rm -Rf `pwd`/{foo,bar,baz}'
However this is needlessly complicated. You don't need `pwd/` in front of file names! Just write
alias cleanup='rm -Rf -- {foo,bar,baz}'
(the -- is needed if foo might begin with a -, to avoid its being parsed as an option to rm), which can be simplified since the braces are no longer needed:
alias cleanup='rm -Rf -- foo bar baz'

Resources