I want to write an alias command for 'ls', so that if I pass in a parameter, then the alias will use it, but if I do not, then it would use '*' instead. This is the alias I have today:

alias lsd='ls --color -lh | grep "^d" && ls --color -lh | grep -v "^d" 

My problem is that no matter what I type for the lsd command, I always get all files in the response. So, when I type lsd *.sh, I still get all directories and files in the listing.

I copied this alias from another SuperUser post but don't really understand it yet.

Thanks for any help.

UPDATE: Ok, now I have this function defined in my .bashrc file:

function lsd() { if [[ -z $1 ]] ; then command ls --color -lh | grep "^d" && ls --color -lh | grep -v "^d" else command ls --color -lh "$1" | grep "^d" && ls --color -lh "$1" | grep -v "^d" fi } 

When I run that with just lsd, it works as I want. When I run it with lsd *.wav though, I still get the directory names in the output and then I see "Binary file x.wav matches output". What am I doing wrong?

In case it's not clear, I am trying to list directories and then files, but only those matching the first parameter in the command. So when I enter lsd *.wav, I don't expect to see directories since their names don't end with .wav. Thanks for all the help! :)

LAST: Never mind. I was using source .bashrc to try to update bash but that wasn't working so the old commands were still running. I closed my ssh session and logged back in and this new command is working now. Thanks all!

0

4 Answers

Aliases do not take parameters. Use alias if you only want to replace a long string by a short one. For parameter processing, use a function:

ls () { if [[ -z $1 ]] ; then command ls * else command ls "$@" fi } 
7

Use -z to check if the variable isn't set.

alias ls='[ -z $1 ] && ls * || ls $*' 
4

As others have said, "alias" doesn't process the command line arguments given on the command line that invokes the "aliased" command. It simply passes along all the command line arguments to the substituted command by appending the arguments to the end.

Here is an example test script to show this effect...

Start with a script like this:

[~]# cat / #!/bin/sh dollarpound="$1" shift dollarone="$1" shift echo "" echo "dollarpound=\"$dollarpound\"" echo "dollarone=\"$dollarone\"" echo "\$*=\"$*\"" echo "\$@=\"$@\"" echo "\$1=\"$1\"" echo "\$2=\"$2\"" echo "" if [ $# -eq 0 ]; then echo ls --color -lh * else echo "ls --color -lh $*" fi echo "" [~]# 

Then, assign that script to an alias:

[~]#alias lsx='/ $# "$1"' [~]# 

Invoke the alias lsx with no arguments:

[~]# lsx dollarpound="0" dollarone="" $*="" $@="" $1="" $2="" ls --color -lh ant bat cat dog eel.txt fox.txt goat.jpg horse.jpg [~]# 

Invoke the alias lsx with 1 argument: "*.txt":

[~]# lsx *.txt dollarpound="0" dollarone="" $*="eel.txt fox.txt" $@="eel.txt fox.txt" $1="eel.txt" $2="fox.txt" ls --color -lh eel.txt fox.txt [~]# 

Notice that the script invoked by the "aliased" command reports 0 arguments instead of 1 ("*.txt"), or 2 ("eel.txt", "fox.txt").

Invoke the alias lsx with 4 arguments:

[~]# lsx ant bat cat dog dollarpound="0" dollarone="" $*="ant bat cat dog" $@="ant bat cat dog" $1="ant" $2="bat" ls --color -lh ant bat cat dog [~]# 

Notice that the script invoked by the "aliased" command reports 0 arguments instead of 4.



So, a working version of the script is:

[~]# cat / #!/bin/sh if [ $# -eq 0 ]; then \ls --color -lh * else \ls --color -lh $* fi [~]# 

(Notice the \ before ls. This prevents ls from being further substituted by other "aliases", etc...).

Assign the working script to an alias:

# alias lsx='/ [~]# 

Invoke the alias lsx with no arguments:

[~]# lsx -rw-r--r-- 1 someuser someuser 0 Jan 21 02:42 eel.txt -rw-r--r-- 1 someuser someuser 0 Jan 21 02:42 fox.txt -rw-r--r-- 1 someuser someuser 0 Jan 21 02:42 goat.jpg -rw-r--r-- 1 someuser someuser 0 Jan 21 02:42 horse.jpg ant: total 0 bat: total 0 cat: total 0 dog: total 0 [~] 

Notice that the script detected there were no arguments and ran "ls *" instead of "ls" (with no arguments).

Invoke the alias lsx with 1 argument: "*.txt":

[~]# lsx *.txt -rw-r--r-- 1 someuser someuser 0 Jan 21 02:42 eel.txt -rw-r--r-- 1 someuser someuser 0 Jan 21 02:42 fox.txt [~] 

Invoke the alias lsx with 4 arguments:

[~]# lsx ant bat cat dog ant: total 0 bat: total 0 cat: total 0 dog: total 0 [~]# 

If there is a reason you want to do this with an "alias", this should work for you. Just just give the alias and the script whatever names you like. For example, if you wanted to "alias" the ls command, use alias ls='/ (with the path and name you used for the script).

On the other hand, if you want this command to be uniquely named, like lsx for example, it might be simpler to just give the script that name, and put the script in a folder that is included in the path, like: /bin/lsx, or whatever you like.

I wanted to alias a command, so I could do something different when it's run.

For example, I wanted to have it so

$ git push

did some other things first, before pushing. I know I could probably handle this in a git way, but this is a general solution to the problem of wanting to alias a command and it's arguments.

I created an alias like so, that points to a bash script:

$ alias git="$HOME/bin/git"

I then created a bash script to intercept certain git calls

~/bin/git

#!/usr/bin/env bash # avoid recursive calls to this bash script if [ "$IN_GIT_BIN" != "true" ]; then # intercept calls to "git push", and do something if [ "$1" == "push" ]; then shift; echo "using ~/bin/git ...." IN_GIT_BIN="true" do_extra_things "$@" exit; fi fi # if not intercepted, run original git command /usr/local/bin/git "$@" 

This allows me to have other scripts that use git in them, and they wont use my git override, they'll use the original binary of git instead.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy