LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-17-2012, 05:15 AM   #1
kopert
LQ Newbie
 
Registered: Sep 2012
Posts: 3

Rep: Reputation: Disabled
Bash - command substitution


Hi Everyone,
I am new to bash scripting and I just recently encountered a problem:
I want to receive all terminal names(tty1, tty2 etc.), which are currently in use (using who command), and filter myself of the result.

So I do this in command line:
echo "$(who | cut -b10-20 | grep -v {$(who am i | cut -b10-20)})"

It seems that problem is in passing parameter -v {$(who am i | cut -b10-20)}

I know that there are different ways to solve this problem, using functions etc. But for learning reasons I would like to know what am I doing wrong.

Thanks
kopert
 
Old 09-17-2012, 05:55 AM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
The first thing I see is that this does not work:
Code:
grep {string} filename
it needs to be
Code:
grep "string" filename
The best way to learn these things is to try to commands individually to be sure how they work.

For your specific problem, I suggest searching on your username, not the terminal #. (eg--using a terminal emulator, I show up twice in the output of "who".

Finally, stringing too much stuff together can lead to problems.
 
Old 09-17-2012, 06:02 AM   #3
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
First of all, please use ***[code][/code] tags*** around your code and data, to preserve formatting and to improve readability. Please do not use quote tags, bolding, colors, or other fancy formatting.


Next, what output do you get? What are the error messages, if any?

Also, what exactly does the who command output for you? I don't have a multi-user system, so I can't run any tests without it. The same goes for whoami, (not "who am i" !). But in any case you can probably substitute the built-in $USER variable instead.

In short, it usually helps when we can see the same things you do.


Don't forget to quote your substitutions, unless you want the output to be word-split afterwards, just like when using variables.


What do you think the "{..}" brackets are supposed to be doing here? In this configuration they would be treated as part of the grep expression. If they were moved inside the "$(..)" then they could be considered a command grouping; but only if the final "}" keyword is separated from the last command with a semi-colon. i.e.

Code:
{ command1 ; command2 ;}
This syntax is necessary when the grouping is all on a single line.

But since the command substitution already acts as a grouping pattern, they wouldn't be necessary anyway.

Finally, the initial echo and substitution brackets are completely pointless. The chain itself will print to stdout.


Assuming the commands themselves are correct, try this:

Code:
who | cut -b10-20 | grep -v "$( whoami | cut -b10-20 )"
who | cut -b10-20 | grep -v "$USER"
There are probably better ways to do this, however.

Last edited by David the H.; 09-17-2012 at 06:04 AM.
 
1 members found this post helpful.
Old 09-17-2012, 06:12 AM   #4
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
Try this:
Code:
me=$(who am i|awk '{print $1}'
who | grep -v $me | awk '{print $2}'
But, note this:
Code:
[mherring@herring_lap play]$ whoami
mherring
[mherring@herring_lap play]$ who am i
mherring pts/0        2012-09-17 06:36 (:0.0)
which leads to this:
Code:
who | grep -v $(whoami) | awk '{print $2}'
Overlap with previous post acknowledged......
 
1 members found this post helpful.
Old 09-17-2012, 06:43 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
So wait, there really is a "who am i" command string? Well, whaddayaknow?

Edit: And how about removing the unnecessary grep too?

Code:
who | awk -v me="$(whoami)" '$0 !~ me {print $2}'

Last edited by David the H.; 09-17-2012 at 06:48 AM.
 
Old 09-17-2012, 07:05 AM   #6
kopert
LQ Newbie
 
Registered: Sep 2012
Posts: 3

Original Poster
Rep: Reputation: Disabled
Thank you for your answers!

Quote:
Originally Posted by pixellany
For your specific problem, I suggest searching on your username, not the terminal #. (eg--using a terminal emulator, I show up twice in the output of "who".
I would like to get all terminal names except one, on wich command was executed.
In your solution user will get all terminal names except those on wich he is logged in.

Quote:
Originally Posted by pixellany
Code:
me=$(who am i|awk '{print $1}'
who | grep -v $me | awk '{print $2}'
This solution works very well, when changing $1 to $2.
However, without using variable "me", this is not working:
Code:
who | grep -v $(who am i | awk '{print $2}') 
who | grep -v $(who -m | awk '{print $2}')
Quote:
Originally Posted by David the H.
First of all, please use *** tags*** around your code and data, to preserve formatting and to improve readability. Please do not use quote tags, bolding, colors, or other fancy formatting.


Next, what output do you get? What are the error messages, if any?

Also, what exactly does the who command output for you? I don't have a multi-user system, so I can't run any tests without it. The same goes for whoami, (not "who am i" !). But in any case you can probably substitute the built-in $USER variable instead.
I am sorry, my bad.

The output of "who" command is:
Code:
testusr1 tty2         2012-09-17 13:12
testusr1 tty1         2012-09-17 13:12
testusr2 tty3         2012-09-17 13:17
testusr3 tty4         2012-09-17 13:04
root     tty5         2012-09-17 13:29
The output of "whoami" command is:
Code:
testusr1
The output of "who am i" or "who -m" is:
Code:
testusr1 tty1         2012-09-17 13:12
The output of command:
Code:
who | cut -b10-13 | grep -v "$( who -m | cut -b10-13 )"

+ who
+ cut -b10-13
++ who -m
+ grep -v ''
 
Old 09-17-2012, 08:32 AM   #7
Snark1994
Senior Member
 
Registered: Sep 2010
Distribution: Debian
Posts: 1,632
Blog Entries: 3

Rep: Reputation: 346Reputation: 346Reputation: 346Reputation: 346
Quote:
Originally Posted by David the H. View Post
So wait, there really is a "who am i" command string? Well, whaddayaknow?
It seems to vary:

Code:
[joshua:~]$ who
joshua   :0.0         2012-09-17 09:42
[joshua:~]$ whoami
joshua
[joshua:~]$ who am i
[joshua:~]
My version of 'who' (GNU coreutils 8.17) certainly doesn't like you adding 'am i' to it... Though I note that I have two manpages for it, and the second one says

Quote:
who [OPTION]... [ FILE | ARG1 ARG2 ]
...
-m only hostname and user associated with stdin
...
If FILE is not specified, use /var/run/utmp. /var/log/wtmp as FILE is common. If ARG1 ARG2 given, -m presumed: 'am i' or 'mom likes' are usual
 
Old 09-17-2012, 11:38 AM   #8
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,928

Rep: Reputation: 612Reputation: 612Reputation: 612Reputation: 612Reputation: 612Reputation: 612
'who' returns the names of all logged-in users, 'whoami' returns the equivalent of the bash environmental variable $USER
 
Old 09-18-2012, 04:13 AM   #9
kopert
LQ Newbie
 
Registered: Sep 2012
Posts: 3

Original Poster
Rep: Reputation: Disabled
Finally I found a way to get all terminal names (except one, on which command was issued), without using variables.

Code:
who | awk '{print $2}' | grep -v "$(ps --no-headers | awk '{print $2}' | uniq)"
Still don't know why it is not working when changing:
Code:
"ps --no-headers" to "who am i" or "who -m" or even "tty".

Best,
kopert
 
  


Reply



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
mkdir in bash script - command substitution casperdaghost Linux - Newbie 3 06-26-2010 05:10 AM
bash: case and command substitution--what gives? David the H. Programming 9 09-03-2009 02:08 AM
bash script command substitution and quoting brian4xp Linux - Software 8 02-05-2008 11:43 AM
BASH command substitution that starts with a pipe | Kristofer Programming 4 02-27-2007 05:52 PM
Bash Command Substitution dakensta Programming 5 11-30-2006 03:10 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:32 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