If what you want is a command cmd so that cmd cr* lists cron.daily itself, then that command is ls -d. If that's too much typing, you can define an alias. For example, put this line in your ~/.bashrc:
alias l='ls -d'
Then running l cr* will display information about cron.daily itself, while ls cr* will list the contents of the directory cron.daily (and of any other directory matching the pattern and any other non-directory matching the pattern).
ls -d does work. It does exactly what you asked it to: it lists the current directory itself. That may not be very useful — ls -ld is somewhat useful, but not ls -d — but computers do what you tell them to do, they don't read your mind to find out what you wanted.
If what you want is to get the effect of ls -d, except that with no arguments you get a listing of the current directory, you can define a function.
l () {
if [ $# -eq 0 ]; then
ls -l
else
ls -ld "$@"
fi
}
Then l cr* lists the files whose name begins with cr, even if they're directories. And l cron.daily lists cron.daily itself, not its contents; you can use ls cron.daily or l cron.daily/* to list the contents. But l lists the files in the current directory.
With the function above, l -a will pass the -d flag. If you don't want that, you can make the function discard options when determining whether it has file name arguments.
l () {
local a
a=("$@")
while [[ $1 = -* ]]; do shift; done
if [ $# -eq 0 ]; then
ls -l "${a[@]}"
else
ls -ld "${a[@]}"
fi
}
If what you want is a command cmd so that cmd cron.daily lists the files in the subdirectory cron.daily, but cmd cd* lists cron.daily itself, then this is impossible in bash. By the time the command is executed, the shell has expanded the wildcards, and the command cannot know whether you used wildcards or not.
This is possible in zsh, because in zsh you can disable wildcard expansion for a specific command. Zsh isn't the default shell on most systems, but it's just one package installation away. In zsh, you can define an alias with the noglob prefix:
alias l='noglob list_files_or_directory_contents'
You'll then need to define that list_files_or_directory_content function — your requirement is uncommon, so it probably doesn't exist yet. Here's a function that I think does what you're after: list the contents of directories specified directly, and list the directories themselves if they come from a wildcard expansion.
list_files_or_directory_contents () {
local arg matches
setopt local_options no_csh_null_glob no_null_glob no_nomatch no_glob_subst no_sh_word_split
if (($#==0)); then
# No arguments: list the directory itself
ls -l
else
for arg; do
matches=($~arg)
if [[ $#matches -eq 1 && $matches[1] == $arg ]]; then
# Not a wildcard pattern: list the directory contents if it's a directory
ls -l -- $arg
else
# Wildcard pattern: list the matches themselves, even the ones that are directories
ls -ld -- $matches
fi
done
fi
}
lscommand and behave the way you want it to, as a solution.ls. Unix is not MS-DOS or CMD.EXE....it's also not hard to learn basic things like this.ls -dworks! It just displays the current directory (.), like you asked it to.