LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 12-09-2017, 07:20 AM   #1
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Rep: Reputation: 51
Question Bash: how to avoid a command inside an alias being used as another alias?


My shell is bash. I use several aliases for many things, I like them. Sometimes, when I need to run the "raw" command, I use single quotes in its name. Compare:

Code:
$ alias ls='ls -sh --color=auto'

$ ls                             # my normal ls
total 4,0M
 20K aaa.txt
 20K aab.txt
 20K aac.txt

$ 'ls'                           # raw/real command
aaa.txt
aab.txt
aa3.txt

$ # Now I did a command to count number of files:
$ 'ls' | wc -l                   # it needs single quotes to avoid my alias
3

$
I want to make that command as an alias. I tried escaping the quotes, also with double quotes to limit the alias, ... the result was either: wrong count (would be 4 in the above example) due my normal ls being used; or an error saying that 'ls' (quotes included in the name!) does not exist.

How to avoid a command inside an alias being used as another alias? I want it to be the same it is when I single quote it in the command line.
 
Old 12-09-2017, 08:08 AM   #2
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
Put the full path for ls?
Code:
alias bla="/bin/ls | wc -l"
 
1 members found this post helpful.
Old 12-09-2017, 08:20 AM   #3
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Talking

hahaha... that was too easy. hahaha

The problem to discover it for myself was issues in finding the right thing with the words I had to search for. Tricky, really tricky.

Thank you very much! (:
 
Old 12-09-2017, 12:25 PM   #4
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,804

Rep: Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203
Alternatives to /bin/ls are
\ls
command ls
 
Old 12-09-2017, 12:40 PM   #5
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Quote:
Originally Posted by MadeInGermany View Post
Alternatives to /bin/ls are
\ls
command ls
Is that an escaped L for itself? So, the consequence is that approach would not work for all letters, right?

If my idea is *not* right, the \ can sometimes be easier to type...
 
Old 12-09-2017, 03:17 PM   #6
suicidaleggroll
LQ Guru
 
Registered: Nov 2010
Location: Colorado
Distribution: OpenSUSE, CentOS
Posts: 5,573

Rep: Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142Reputation: 2142
Quote:
Originally Posted by dedec0 View Post
Is that an escaped L for itself? So, the consequence is that approach would not work for all letters, right?

If my idea is *not* right, the \ can sometimes be easier to type...
You're escaping the command, it works for all commands AFAIK.
 
1 members found this post helpful.
Old 12-09-2017, 04:32 PM   #7
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Smile

Quote:
Originally Posted by suicidaleggroll View Post
You're escaping the command, it works for all commands AFAIK.
Escaping commands... nice idea. Never heard of that! Is this Bash only? Or did it exist since sh?
 
Old 12-09-2017, 05:35 PM   #8
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Question

Quote:
Originally Posted by suicidaleggroll View Post
You're escaping the command, it works for all commands AFAIK.
I found it strange to have not read about that before. I read parts of bash manual frequently. I did read bash manpage now, imagining it would say something about escaping commands. It does not! I have read all parts of it that contain the "escap" word. Where is that written?
 
Old 12-09-2017, 08:24 PM   #9
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,780

Rep: Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213
From the bash manpage:
ALIASES
Aliases allow a string to be substituted for a word when it is used as the first word of a simple command. The shell maintains a list of aliases that may be set and unset with the alias and unalias builtin commands (see SHELL BUILTIN COMMANDS below). The first word of each simple command, if unquoted, is checked to see if it has an alias.
The backslash quotes the first character of the command, preventing the alias expansion.

Last edited by rknichols; 12-09-2017 at 08:28 PM.
 
1 members found this post helpful.
Old 12-10-2017, 04:44 AM   #10
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Quote:
Originally Posted by rknichols View Post

(...)

The backslash quotes the first character of the command, preventing the alias expansion.
But "The backslash quotes...": that is not even close obvious to me.
 
Old 12-10-2017, 07:24 AM   #11
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,780

Rep: Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213
Quote:
Originally Posted by dedec0 View Post
But "The backslash quotes...": that is not even close obvious to me.
That is what the backslash character does. It quotes the character that follows it. It's commonly used to quote characters like asterisk that would otherwise be special to the shell, but applies also to any other character that might, under some conditions such as an alias expansion, be treated specially.
 
Old 12-10-2017, 09:03 AM   #12
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Quote:
Originally Posted by rknichols View Post
That is what the backslash character does. It quotes the character that follows it. It's commonly used to quote characters like asterisk that would otherwise be special to the shell, but applies also to any other character that might, under some conditions such as an alias expansion, be treated specially.
I never, in my whole life, have seen anyone calling that "quoting". And I have been in IT area since many years ago. The idea of escaping (the IT jargon I know, and have for a long time too) is not even close to be applied to backslashes (I would call it "backslash escaping", but I decided to use a shorter option here).

You have inspired me to do a few more tests in my terminal. Read them thinking about 3 ways to "quote" things: backslah, single, double quotes, backslash inside quotes. Look:

Code:
$  touch 1asd\ lkj '2asd lkj' "3asd lkj"; alias ll='ls -l'; ll
1asd lkj
2asd lkj
3asd lkj

$  touch 4asda\nlkj '5asda\nlkj' "6asda\nlkj"; ll
1asd lkj
2asd lkj
3asd lkj
4asdanlkj
5asda\nlkj
6asda\nlkj

$  touch 7asdb*lkj '8asdb*lkj' "9asd*lkj"; ll
1asd lkj
2asd lkj
3asd lkj
4asdanlkj
5asda\nlkj
6asda\nlkj
7asdb*lkj
8asdb*lkj
9asd*lkj

$ # There was one extra "9" file in my tests, it is a mistake I did
$ # But it made me discover a new question! So I keep it here.
$ # Continue reading... the next command is *not* repeated!
$  touch 7asdb*lkj '8asdb*lkj' "9asdb*lkj"; ll # 9 with b
1asd lkj
2asd lkj
3asd lkj
4asdanlkj
5asda\nlkj
6asda\nlkj
7asdb*lkj
8asdb*lkj
9asdb*lkj
9asd*lkj

$  rm 9asd*lkj  # this argument, without "b" and "\", pressing TAB after "J",
$  # expands to 9asdb\*lkj ! It should not!
$  # Why? It had two possibilities, it *chose* the first!
removido '9asd*lkj'

$  ll
1asd lkj
2asd lkj
3asd lkj
4asdanlkj
5asda\nlkj
6asda\nlkj
7asdb*lkj
8asdb*lkj
9asdb*lkj

$  touch 10*asd*; ll  # does not touch any existing, but creates one file!
1asd lkj
2asd lkj
3asd lkj
4asdanlkj
5asda\nlkj
6asda\nlkj
7asdb*lkj
8asdb*lkj
9asdb*lkj
10*asd*

$ # We could expect no arguments should exist in this expression
$ # The reason I did it was just to test "almost equal" things.
$ # Look bvious, but...

$ # change prompt to have clock with seconds

12:31:00 [ this is PS1 now]
$  touch *asd*; ll
dez 10 12:31 10*asd*
dez 10 12:31 1asd lkj
dez 10 12:31 2asd lkj
dez 10 12:31 3asd lkj
dez 10 12:31 4asdanlkj
dez 10 12:31 5asda\nlkj
dez 10 12:31 6asda\nlkj
dez 10 12:31 7asdb*lkj
dez 10 12:31 8asdb*lkj
dez 10 12:31 9asdb*lkj

12:31:37 [ this is PS1 now]
$  touch '*asd*'; ll  # only after 12:32:00!
$  # it did not touch, just created one file
dez 10 12:31 10*asd*
dez 10 12:31 1asd lkj
dez 10 12:31 2asd lkj
dez 10 12:31 3asd lkj
dez 10 12:31 4asdanlkj
dez 10 12:31 5asda\nlkj
dez 10 12:31 6asda\nlkj
dez 10 12:31 7asdb*lkj
dez 10 12:31 8asdb*lkj
dez 10 12:31 9asdb*lkj
dez 10 12:32 *asd*

12:32:57 [ this is PS1 now]
$  touch "*asd*"; ll  # only after 12:33:00!
$  # it did not create a file, just touched the most recent
dez 10 12:31 10*asd*
dez 10 12:31 1asd lkj
dez 10 12:31 2asd lkj
dez 10 12:31 3asd lkj
dez 10 12:31 4asdanlkj
dez 10 12:31 5asda\nlkj
dez 10 12:31 6asda\nlkj
dez 10 12:31 7asdb*lkj
dez 10 12:31 8asdb*lkj
dez 10 12:31 9asdb*lkj
dez 10 12:33 *asd*

12:33:40 [ this is PS1 now]
$
I will make a *separate* post for the question I discovered in these tests. Please wait, if you want to answer it. I will be easier to quote, and I am doing it now.
 
Old 12-10-2017, 09:14 AM   #13
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,780

Rep: Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213
It gets very messy, especially with all the special cases of backslash within double quotes. And, tab completion does not respect wildcards -- all the preceding characters in the word are taken literally.
 
Old 12-10-2017, 09:24 AM   #14
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,893

Rep: Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317Reputation: 7317
if you want to understand bash probably you can use set -x:
Code:
user@host:/tmp$ touch *asd*    # << this is what you entered
+ touch '*asd*'                # << this is what was execcuted after evaluation of command line
 
Old 12-10-2017, 09:30 AM   #15
dedec0
Senior Member
 
Registered: May 2007
Posts: 1,372

Original Poster
Rep: Reputation: 51
Question Why this expansion is chosen by the shell?

Do not miss my previous post. It is important. This one is just for a new question, in the title, that also makes the thread to be unsolved, not a new thread - seemed better.

The following situation happens in a Debian 9 using with bash shell. Look at these commands:
Code:
$  touch "9asd*lkj"; ll
9asd*lkj

$  touch "9asda*lkj"; ll
9asda*lkj
9asd*lkj

$  # Before pressing enter for the next command, I tried to expand the argument.
$  rm 9asd*lkj
The argument to rm, as shown, is expanded to one of the two choices it had! It expands to "9asda\*lkj" - without the quotes, plus a space that possibly expected an argument. We normally conclude that the *only* possible file was found, then - at least me. Wouldn't you?

Do you consider this a bug in Bash? I do, but I would like to see more opinions in this.
 
  


Reply

Tags
bash



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
bash script to display alias commands and un-alias any less than 12 characters bani Linux - Newbie 5 01-19-2014 12:34 PM
bash: command works at command line, but not via an alias porphyry5 Programming 3 03-17-2012 02:48 PM
Using an alias inside a function in bash martindl Linux - Newbie 1 06-08-2011 11:55 PM
Using shortcuts/alias inside a Linux Bash Command pratap.iisc Linux - General 3 01-30-2010 04:52 AM
Creating mult command alias in BASH labob Linux - Newbie 1 11-18-2004 07:37 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 05:59 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration