Linux alias chain commands (can recursion be avoided?) - linux

I've been looking around for ways to alias clear and ls into one command.
Currently I've defined command x:
alias x="clear;ls"
Now is there any walkaround to avoid recursion and define:
alias ls='clear;ls'

If you put a backslash before the command name, that will disable any aliases.
alias ls='clear;\ls'
Or, like Arnaud said, just use the full path for ls.

Another way of doing this would be
alias ls='clear; command ls'
This is different from /usr/bin/ls, as it still searches ls in the $PATH, but will ignore shell functions or aliases.

Just do :
alias ls='clear;/usr/bin/ls'
When typing:
$ ls
First of all it will search an user defined function, it will launch it, else search in $PATH commands.
By giving the explicit path of the ls command, recursion will be avoided.

There is no direct recursion in alias. From man bash:
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 may alias ls to ls -F, for instance, and
bash does not try to recursively expand the replacement text.

I always use ls with --color=auto parameter ( -G Enable colorized output.) and like to use functions.
clear_and_ls() {
clear
command ls --color=auto
}
alias ls="clear_and_ls"

Related

Alias to Scrot program doesn't work in .bashrc but works in terminal

I'm trying to alias a scrot command in .bashrc with this:
alias scrotn="scrot %Y-%m-%d-%s_$wx$h.jpg -e 'mv $f ~/pictures/screenshots/'"
The scrot command works in my terminal but when I try to run scrotn i receive this output:
mv: missing destination file operand after '/home/lain/pictures/screenshots/'
Already tried adding quotes to %Y-%m-%d-%s_$wx$h.jpg, switching double and single quotes and using /home/lain/ instead of ~/. Yes, ~/pictures/screenshots/ exists. I wanna create an alias to bind it to the PrtSc key in my DWM config.
Sorry for poor english.
Since the alias is defined as a double-quoted string (the inner quotes do not matter for the shell) $f is expanded (presumably to the empty string) when the alias is created. The recommended way to work around this would be to use a function rather than an alias. Aliases are considered deprecated by many, because they can do less than functions, are hard to debug as you've discovered, and are really not much simpler than functions.
The result:
scrotn() {
[your scrot command line]
}

How to use alias to call alias in bash file? [duplicate]

Background:
I'm trying make a function that runs commands on a set interval because I don't have access to a "watch" program. Simplified to it's most basic from, the function I'm trying to write is runit() { $1; }.
What works:
This works fine and dandy when I pass it things that aren't aliases. For example, runit "ls -l" works fine. I get the full output from the ls -l command.
What doesn't work:
The problem starts when I pass it an alias. For example, setting alias ll="ls -l" then calling runit "ll" will result in -bash: ll: command not found.
Things I have tried:
When I hard-code the alias runit() { ll; }, it works fine and gives me what I expect.
I feel like I might be overlooking something, but I can't quite place my finger on it.
Why would hard-coding the alias work fine, but passing it into the function fail?
Is there a way to accomplish what I'm attempting to do?
From the bash man page discussion of aliases (emphases mine):
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.
You can observe this effect in functions by using the type command:
$ run_it () { ll; }
$ type run_it
You should see that the body of the function contains a call to ls -l, not ll.
The last sentence of the section on aliases:
For almost every purpose, aliases are superseded by shell functions.
My interpretation of that line is: if you think you want to use an alias, try writing a function first. Don't use an alias unless the function demonstrably fails to do what you need.
You can use eval like this:
$ runit() { eval $1; }
$ alias ll="ls -l"
$ runit "ll"
eval will expand any alias in $1 before the execution.
One way to solve this problem is to define a shell function rather than an alias.
ll () {
ls -l "$#"
}
The alias is expanded as a macro on command input, whereas the shell function is matched when the command is executed. This is a perfect example of how the shell's macro processor language is good for interactive grace but rather complicates actual programming.

Automatically appending --exclude-dir=xxxx (multiple dirs) to grep bash command?

I'd like to automatically exclude several 3rd party library folders so I don't have to retype it every time. How would one accomplish such a task?
You can either create an alias
alias grep='grep --exclude-dir=xxxx'
that you would add to your .bashrc, or setup an environment variable
export GREP_OPTIONS='--exclude-dir=xxxx'
that you would add to your .bash_profile.
Note that aliases only work at the beginning of a command line (start of line, or after a pipe, or an opening parenthese, etc.) Consequently, ... | xargs grep ..., for instance, won't use the alias. By contrast, the env variable will be honored, which can have its downsides as mentioned below.
You can alias grep to always include the parameter. On your ~/.bashrc:
alias grep="grep --exclude-dir=xxxx"

How do I set tilde expansion in zsh?

I am trying to achieve expansion of the tilde into the $HOME variable with zsh, and was wondering what best practice is in this case?
Basically what I want is that:
$ ls ~
on pressing TAB expands to
$ ls /home/myusername
where HOME=/home/myusername. The _tilde function usually does a ldap search, followed by named dirs, followed by the dir stack, none of which I need.
What is the best way to achieve this?

How to use grep to find data conveniently and quickly

I am asking for general opinions on how to find files quickly.
One typical scenario is that I often need to grep some names from a PeopleNameFile.txt from Dir1. When I'm in a different directory, I am forced to grep the file with a long directory path. It would be nice to just do GREP "Warren Buffett" PeopleNameFile.txt.
BTW, I'm using Cygwin but I welcome any suggestions.
You can easily write a simple bash function in your ~/.bashrc:
function grnm() {
grep "$#" /path/to/peoplenamefile.txt
}
Then later on, at command line you can type:
$ grnm "Warren Buffet"
the nice thing is that you can actually include other grep parameters if you like as in:
$ grnm -i "warren buffet"
(The $ characters represent your shell prompt, not part of the command you type.)
When you edit the .bashrc file FOR THE FIRST TIME you may have to source it in your existing open cygwin windows:
$ source ~/.bashrc
But if you open a new window you should not have to do that.
Good luck, have fun
You can create script my_grep.sh and add it somewhere to you path, with content like this:
#!/bin/bash
grep $1 path/to/Dir1/PeopleNameFile.txt
than you just type
my_grep.sh "Warren Buffett"
also you can use alias and bash's function,
but this require to edit "~/.bashrc".
Simplest option would be to setup an alias which would grep for that file using the absolute path. Not sure whether cygwin allows aliases though.
Probably the most common way to do these kind of things is to use environment variables
e.g.
PNF='/very/long/path/PeopleNameFile.txt'
grep "Warren Buffett" $PNF

Resources