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.
Related
I'm trying to have a alias command and the part of its path keeps changing.
Eg:
/var/mywork/swag/wsnew/
/var/mywork/swag/ws/
/var/mywork/swag/wsold/
and my alias command to achieve is something link this
alias cws='cd /var/mywork/swag//
since last directory in the path is keep changing. I wanted to get automatically update in alias command. Is there anyway ?
I tried something like
alias cws='cd /var/mywork/swag/getenv("WSP")/
so whenever I set WSP to required path it automatically takes. But it didn't help.
Like most problems with aliases, this is easier to solve with a shell function:
cws() {
cd /var/mywork/swag/"$WSP"
}
Like melpomene said, you are better off using a function, but if you, for whatever reason, want to stick with an alias, you can do
alias cws='cd /var/mywork/swag/$WSP'
But note that this differs from using a shell function in one point, which is related to setting a variable for just one command: If you write
WSP=aaa
...
WSP=xxx
...
WSP=yyy cws
and cws is defined as a function, this would cd to yyy, but if it is an alias, it would cd to xxx.
I am writing my own unix scripts so I want to add a new directory for Bash. I add sth in .bash_profile like this.
PATH="~/Documents:${PATH}"
export PATH
and in my ~/Documents, there is a file named test of which the content is
#!/usr/bin/env python3.5
print("hahahhah")
I also used
chmod 755 test
to make it executable.
But I cannot call it in terminal directly. ./test works as usual.
What went wrong?
After I change to
PATH="$HOME/Documents:${PATH}"
export PATH
nothing happens.
FDSM_lhn#9-53:~/Documents$ test
FDSM_lhn#9-53:~/Documents$ ./test
hahahhah
Solution:
The fundamental reason is that I have a command of the same name as default one, So it won't work any way! Changing name will be sufficient!
Tilde doesn't get expanded inside strings. So by quoting the right-hand side of the assignment you prevent it from being expanded and get a literal ~ in your PATH variable which doesn't help you any.
You have two ways to fix this:
Drop the quotes on the assignment (yes this is safe, even for $PATH values with spaces, etc.).
Use $HOME instead of ~.
I prefer the second solution but the first is entirely valid for this case.
Beware though that in places where you aren't doing a straight assignment you often cannot just drop the quotes and trying to use ~ will cause problems.
In which case you will end up finding a question like this with an answer like this and something ugly like this.
In Bash, I'd like to create a binding in my .inputrc that makes use of the !! built-in to repeat the last command. But this doesn’t seem to properly expand the !!
bind -x '"\C-t": echo $(!!)'
When I invoke the above binding (Ctrl+t) I just get this:
-bash: !!: command not found
Likewise the simpler
bind -x '"\C-t": echo !!'
Just yields
!!
Instead of the actual command.
Obviously my real use-case is more substantive than this example, this is just an illustration of the problem.
Edit:
This question has nothing to do with echo "#!" fails -- "event not found" which it is claimed mine is a duplicate of. That question pertains to a generalized failure of !* expansion in regular bash due to quoting issues or lack of history. My question on the other hand is very specific to the context of being used inside an .inputrc file (or perhaps an alias), where a different set of factors come into play. On my regular command line, the so-called "bang expansions" have always worked fine. It's only in these special contexts where the problems arose, and hence led to this question.
"\C-t": "fc -s\n"
fc -s re-executes the last command, and fc is also a builtin:
$ type fc
fc is a shell builtin
Well it seems there's something odd going on with shell quoting.
This does not work
bind -x '"\C-l": "!! \n"'
But putting this in .inputrc does
"\C-l": "!! \n"
Don't really understand why the former doesn't work, but at least the latter does.
EDIT: OK got it. Apparently the "-x" isn't needed when defining on the cmd line. So we can simply write
bind '"\C-l": "!! \n"'
Using -x tells bind not to interfere with what you've already typed (almost like a primal ncurses approximation of a modal window!) which is not what I'm after. Thanks to the accepted answer on In bash, how do I bind a function key to a command? for this insight!
I'm trying to update some scripts from tcsh to bash to reflect the bash preference of some users. Needless to say, I don't know csh. Can someone tell me what this line does?
alias prepend 'if (-d \!:2) if ("$\!:1" \!~ *"\!:2"*) export \!:1 "\!:2":${\!:1}'
That probably prepends a directory onto a variable if said directory doesn't already exist in said variable.
Here's what it says, in English: if the second argument is a directory, then if the first argument interpreted as a variable does not contain the text of the second argument, then "export" the string "second argument colon contents of first argument" into the first argument.
It all depends upon what export does. In my experience, export is an alias for setenv, but that is not guaranteed.
I would suggest a test to see if this does what I think. First, echo your path. Then run prepend PATH /a/new/directory/that/exists. Then echo your path again. If you see that "/a/new/directory/that/exists" is now in your path variable, then you can be reasonably sure export is an alias for setenv.
Finally, this SO post lists strategies to implement a similar thing in other languages and shells.
Say I have the following alias.
alias pwd_alias='echo `pwd`'
This alias is not "dynamic". It evaluates pwd as soon as the shell starts. Is there anyway to delay the evaluation of the expression in the ticks until the alias's runtime?
What you really want is a function, instead of an alias.
pwd_alias() {
echo "$PWD"
}
Aliases do nothing more than replace text. Anything with complexity calls for a function.
As jordanm said, aliases do nothing more than replace text.
If you want the argument of echo to be the output of pwd expanded by bash, then I don't understand your question.
If you want the argument of echo to be `pwd` with the backquotes kept, it's indeed possible, for example:
alias a="echo '\`pwd\`'"
So, if instead of echo you have something which does backquote expansion in its own runtime, maybe that's what you want.
I do not believe you can change the evaluation from occurring at shell start. Since the processes of creating the alias is run at shell start the pwd is evaluated then. You could simple change the alias to just run pwd without the back ticks as pwd outputs without the need to echo. A simple way to resolve this is to change from using an alias to a shell script in your path if you do not wish to change from using an alias.
#!/bin/bash
pwd