How to make an alias not immediately execute - shell

I'm adding some aliases to my .zshrc file and wondering if I can add an alias that doesn't execute immediately?
Example of usage I want:
I want to be able to have an alias for creating a new git branch
Ideally I can type the alias gcb which will output git checkout -b in the terminal and doesn't execute, then I can add the new branch name and hit enter.
Note:
I know I can do the following:
command alias_name to prevent the alias immediately executing, but I'm seeking a way to do this without the command keyword as having to type that extra text almost defeats the purpose of the alias shortcut
Thanks!

A definition
alias foo=bar
immediately defines the alias foo in the current zsh process. If you later type
foo x y
the command bar x y is executed. Note that by definition of zsh, this behaviour only works in interactive shells. If you want to exploit this in a shell script, you have to enable alias expansion explicitly.

Related

Use semicolon character ";" in bash alias

Got a new annoying keyboard and I'm always typing ;s instead of ls.
Is there a way to create a sort of alias for this?
I tried this: alias ;s="ls" but of course it does not work!
You cannot. You can escape the ; when you run the command, but then alias itself informs you that the name is invalid.
$ alias \;s=ls
bash: alias: `;s': invalid alias name
You could define a Readline macro to replace ;s with ls before the shell tries to parse it:
$ bind '";s": "ls"'
This command can be added to your .bashrc file. (You could add it a definition to .inputrc, but it is unlikely you would want to use this macro in any other Readline-aware program.)

Why do csh(tcsh) aliases not work when defined and invoked on one line?

[Please do not recommend I not use csh. The Electrical Engineering community is inextricably bound to it. Thanks!]
When I do this:
csh -f -c "alias foo bar; foo"
I get:
foo: Command not found.
Similarly, when I do this:
#!/bin/csh -f
alias foo bar; foo
I get the same foo: Command not found.. However, this works as expected:
#!/bin/csh -f
alias foo bar
foo
Which gives:
bar: Command not found.
Is this just a bug in csh/tcsh? Or is this intentional? I have to deal with aliases since the environment I'm using depends heavily on them to configure toolsets (including modules). But this basically means I can't invoke short csh scripts with csh -f -c. I have to dump the commands to a file, chmod +x, and invoke it. Not a huge deal. But I'm just wondering if there's a way to trick this buggy/quirky shell into recognizing aliases defined on the same line.
This is documented behavior of csh: alias substitution happens after each input line is read and split into commands, but before any of the commands are executed (including your alias command).
From csh(1) manual:
Alias substitution
The shell maintains a list of aliases that can be established, displayed
and modified by the alias and unalias commands. After a command line is scanned, it is parsed into distinct commands and the first word of each
command, left-to-right, is checked to see if it has an alias. If it
does, then the text that is the alias for that command is reread with the
history mechanism available as though that command were the previous
input line. The resulting words replace the command and argument list.
If no reference is made to the history list, then the argument list is
left unchanged.

Print terminal alias command as well as executing it

As a terminal noob, I've created aliases for pretty much everything I do. The problem is that I've started forgetting those few commands that I do know because of it. On top of that, I sometimes need to edit a variable in the previous command.
So what I'd like is if when I use an alias, the first line printed is the actual command it represents, then proceed to execute the command. Since pressing up and !! simply reprints the alias, I'm not too sure how to get a reference to the underlying command.
Thanks.
You can always use:
alias to list all your aliases, or
alias name to show the specification of the alias name.
So in fact you can define your alias as
alias myalias="alias myalias; <do stuff>"
I also think that chepner's answer with Alt-Control-e is more practical, but I am posting this for completeness.
After you type your alias, but before you hit enter, you can type Meta-Control-e (probably Alt-Control-e, but possibly Esc-Control-e) to expand what you've typed; this will expand any aliases and history expansions so you can see the "long" form of what you've typed.
You can use variables in your alias to get a clean output:
alias test='_TMP="pushd /home/a/b/c";echo $_TMP; eval $_TMP'
If you want to avoid messages coming out of alias, you can do
_TMP="pushd /home/a/b/c >/dev/null 2>&1"
It does add an environment var of _TMP.
The old post had error in it.

How to run cd within bash script (outside of subshell)

I am writing a bash script (called gotodir.sh) and would like to change directories during the course of the script, depending on some variables, say cd /home/username/${FOO}/${BAR}.
Just running this as is doesn't work when the process exits, since the directory was changed in the subshell only.
My shell is tcsh. (Yeah, I know... not my choice here.) In my .cshrc file, I want to alias the keyword gotodir to gotodir.sh.
I have read that executing the script with a . or source prefix will cause the script to be run in the same shell (i.e. not a subshell).
I have tried putting the following in my .cshrc file:
alias gotodir . /home/username/bin/gotodir.sh
but this results in the error: /bin/.: Permission denied.
I have also tried using source instead of .
alias gotodir source /home/username/bin/gotodir.sh
but this results in the error: if: Expression Syntax.
How do I accomplish this using a bash script while running tcsh?
When you source a file from tcsh, it tcsh runs the commands. The #! is ignored as a comment because you're not running the file as a script, just reading commands from it as if they'd been entered at the shell prompt.
Your mission is doomed to failure. Only a tcsh cd command can change the current directory of a tcsh process.
But if you're willing to bend a little, you can write a script which runs as a separate process and outputs the name of the directory to cd to. Then set the alias like
alias gotodir 'cd `/blah/blah/thescript`'
Addendum
Adding an argument is possible, but tricky. Alias arguments look like history expansion, with !:1 expanding to the first argument. But quotes don't protect the ! character. You have to backslash it to prevent it being expanded during creation of the aliase, so it can do its work during the execution of the alias.
alias gotodir 'cd `/blah/blah/thescript \!:1`'
Additional quoting may be required to handle arguments and directories with spaces in them.

why is "noclobber" appearing in bash command arguments

There are a bunch of folders in ~/path/ with names that begin with prefix, and I need to access them very frequently. I'm trying to create a shortcut in .bashrc that will make "prefix example" run the command "cd ~/path/prefixexample".
I encountered the same issue with both functions and aliases:
function prefix(){ "cd ~/path/prefix$1"; }
alias prefix="cd ~/path/prefix$1"
When I type "prefix 4" (the folder path/prefix4 does exist), I get:
bash: cd: path/prefixnoclobber: No such file or directory
I don't have admin privileges on this machine, so I can't change some things.
.bashrc already contains a bunch of stuff, but the only relevant thing seems to be "set noclobber". I'm pretty sure replacing arguments with the string "noclobber" is not part of the functionality of the noclobber switch, and commenting this switch out had no effect.
The $1 in the alias command is being replaced with whatever the first argument to the setup script happens to be (apparently, "noclobber"), rather than the argument to the alias/function. You need to do two things:
Get rid of the alias. Aliases aren't flexible enough to do what you want, but an alias will override anything else with the same name (and hence interfere with a better solution).
Use a function:
prefix() { cd ~/path/prefix"$1"; }

Resources