Sorry about the non-informative heading...
What I'm looking for is something like that will allow me to shorten redirecting stdout. I know that executing a command with whitespaces before it does not write it into history, and there are a few "magic" operators, such as "!!", etc.
I'm basically looking for something like that, that would allow me to replace >/dev/null, so, I'll be able to write, for example
git pull !!! and that would be equivalent to git pull>/dev/null
Is there something like this? Am I able to override an existing operator / write a new one?
14 Answers
Alias expansion only looks at the first token / word of a line, so there's no way for git pull !!! to get replaced by alias expansion.
However, redirects work even if placed before the command, so you can do it with an alias:
alias quiet='>/dev/null 'Leaving whitespace at the end of the alias expansion makes bash consider the next token for alias expansion. (This is why it's common to do alias sudo='sudo '). So this won't even break your aliases. Example:
$ ll *.s xyz
ls: cannot access 'xyz': No such file or directory
-rw-r--r-- 1 peter peter 12 Mar 6 20:15 a64.s
-rw-r--r-- 1 peter peter 72 Mar 6 21:03 arm.s
-rw-r--r-- 1 peter peter 30 Mar 15 17:38 foo.s
-rw-r--r-- 1 peter peter 42 Mar 6 13:12 mips.s
$ quiet ll *.s xyz # ll alias expanded successfully, stdout discarded
ls: cannot access 'xyz': No such file or directory
$ # stderr is not redirected. 1 I'd use a function
quietly() { # execute the remaining arguments as a command, but redirect output "$@" > /dev/null
}
quietly git pullOr a function that reads stdin and discards it:
q() { cat > /dev/null; }
git pull | qNeither of these redirect stderr: if something goes wrong, you should know about it.
3Aliasing is possible as indicated by the answer of Peter Cordes. Another approach is setting up an environment variable. This allows for a more natural redirection syntax:
export d0='/dev/null'which you then can use as
git pull >$d0 It is possible, yes, but not through aliases – instead by using bash's extdebug function, which allows making arbitrary changes to a command before it is executed (by suppressing the original command and eval'ing the new one).
shopt -s extdebug
trap "code goes here" DEBUGThe trap handler will get the original input in $BASH_COMMAND, and returning 1 from the handler will cancel original the command. If you enter multiple ;-separated commands, the trap is invoked separately for each one.
Specifically:
shopt -s extdebug
trap 'if [[ $BASH_COMMAND == *!!!* ]]; then eval "${BASH_COMMAND//!!!/"> /dev/null"}"; false fi' DEBUGThis will replace any !!! with > /dev/null anywhere inside the command. You won't be able to do echo 'Hi!!!' anymore.
If you prefer to match only at the end of command, that's easy too.
trap 'if [[ $BASH_COMMAND == *\ quietly ]]; then eval "${BASH_COMMAND% quietly} > /dev/null"; false fi' DEBUGAs another example, you can use this to alias command please to sudo command:
trap 'case $BASH_COMMAND in *\ please) eval sudo ${BASH_COMMAND% *}; false; esac' DEBUGThere is another way to achieve a similar thing: you can redefine keys in Bash (readline) using either bind or ~/.inputrc, which you can also use to redefine key sequences.
For example, inputrc entry "!!!": "> /dev/null" or the equivalent shell command bind '"!!!": "> /dev/null"' will cause the text > /dev/null to be inserted whenever you attempt to type !!!.
Note that Bash cannot predict future, which means that if you only want to type a single !, there will be a slight delay before it appears – that's Bash waiting to see whether it'll match the sequence. This can get annoying, so don't bind letters and stuff.
In fact, it would be a better idea to bind a Ctrl or Alt hotkey instead. For example, you could create a Alt+Q hotkey using "\eq": "> /dev/null".
Previously: