Scripting with unix to get the processes run by users [closed] - linux

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
If I find out I have two users logged (UserA and UserB) in to the systems right now, How do i find out the processes run by those two users. but, the trick here is the script is to be run in an unattended batch without any input from the keyboard. other than being invoked.
I know the first part of the script would be
who | awk '{print $1}'
the output of this would be
UserA
UserB
What I would like to know is, how can I use this output and shove it with some ps command automatically and get the required result.

I finally figured out the one-liner I was searching for, with the help of the other answers (updated for case where no users logged in - see comments).
ps -fU "`who | cut -d' ' -f1 | uniq | xargs echo`" 2> /dev/null
The thing inside the backticks is executed and "inserted at the spot". It works as follows:
who : you know what that does
cut -d' ' : split strings into fields, using ' ' as separator
-f1 : and return only field 1
uniq : return only unique entries
xargs echo : take each of the values piped in, and send them through echo: this strips the \n
2> /dev/null : if there are any error messages (sent to 2: stderr)
: redirect those to /dev/null - i.e. "dump them, never to be seen again"
The output of all that is
user1 user2 user3
...however many there are. And you then call ps with the -fU flags, requesting all processes for these users with full format (you can of course change these flags to get the formatting you want, just keep the -U in there just before the thing in "` `"
ps -fU user1 user2 user3

Get a list of users (using who), save to a file, then list all processes, and grep that (using the file you just created),
tempfile=/tmp/wholist.$$
who | cut -f1 -d' '|sort -u > $tempfile
ps -ef |grep -f $tempfile
rm $tempfile

LOGGED_IN=$( who | awk '{print $1}' | sort -u | xargs echo )
[ "$LOGGED_IN" ] && ps -fU "$LOGGED_IN"
The standard switch -U will restrict output to only those processes whose real user ID corresponds to any given as its argument. (E.g., ps -f -U "UserA UserB".)

Not sure if I'm understanding your question correctly, but you can pipe the output of ps through grep to get the processes run by a particular user, like so:
ps -ef | grep '^xxxxx '
where xxxxx is the user.

Related

How to extract field from command result in different versions of linux?

I was trying to extract a process size using the command:
size=`ps -eo vsz,pid | grep $pid | cut -'d' -f1`
However, this appeared to only work on some computers but not all. So on the ones where it wasn't working, I tried:
size=`ps -eo vsz,pid | grep $pid | awk '{print $1}'`
however, now this didn't work on the computers where the first command worked.
What I mean by "working" and "not working" is that sometimes:
echo "|$size|"
Will return something like:
|8762348
9835|
And thus the following returns an arithmetic error:
(( $size > $threshold ))
because of the newline or carriage return characters stored in $size. Is there a way to reliable extract simply the first field across different versions of linux?
First you ask ps to displat info for all processes, next you try to select 1 of them.
Your command had problems on some computers, and you tagged the question with both ksh and linux, so I am not sure what command can be used best in your case:
size=$(ps -q ${pid} -o vsz --no-headers)
# or
size=$(ps -p ${pid} -o vsz | grep -v "VSZ")

managing user accounts by group name, username and last login linux

I created a script called monitornsuaccounts.sh that should append its output file to useraccountstatus.log. useraccountstatus.log is in the directory /var/local/nsu/logs/.
The output of this script should state every username and the following information about each username: username, last login, user home directory and associated groups. Preferably there should be columns with each information.
The command I use for the usernames is sudo cat /etc/passwd | grep ‘/home’. Last is to find the last login of each user. Groups is to the find the group of each user. When I run the command, the output file only shows the data I need for my current user rather than all users. Any recommendations that anyone has would be greatly appreciated.
#!/bin/bash
usernames=sudo cat /etc/passwd | grep ‘/home’
echo “$usernames” > /home/daniel/names.txt
mlast=$(cat names.txt | xargs -n1 last)
mgroup=$(cat names.txt | xargs -n1 groups)
cat names.txt > /var/local/nsu/logs/useraccountstatus.log
echo “$mlast” >>/var/local/nsu/logs/useraccountstatus.log
echo “$mgroup” >>/var/local/nsu/logs/useraccountstatus.log
There are a lot of issues in your script.
Your definition of users. Are you sure that this is what you want? For example: root does not have a directory under /home.
Watch your quotes. cat /etc/passwd | grep ‘/home’ returns nothing, while cat /etc/passwd | grep 'home' returns a list of stanzas in /etc/passwd
You'll probably want just a list of usernames, not a list of stanzas. Something along the line of
cat /etc/passwd | grep 'home' | sed 's/:.*//'
Why sudo in sudo cat /etc/passwd?
Look at your assignment in the
usernames=sudo cat /etc/passwd | grep ‘/home’
This does not make sense. You might try to do a
usernames=`sudo cat /etc/passwd | grep '/home'| sed 's/:.*//'`
And that is just the first line of the script.
Anyway, if your script does not work as intended, you will need to do some debugging. First question, especially if you are inexperienced, is "do the commands that I write give the result that I expect?" So in your case, you should have tried cat /etc/passwd | grep ‘/home’ and you would have seen that it does not give you the expected results. Even with the correct quotes, you'll get a list of stanzas, which is also not what you expected. Have you looked at /home/daniel/names.txt and was the content of the file what you wanted? I guess not: it was empty.
Just a quick hint, to get you started in the right direction (although there are still some issues and pepole might object to the backtics)
#!/bin/bash
usernames=`sudo cat /etc/passwd | grep '/home'| sed 's/:.*//'`
mlast=`echo $usernames | xargs -n1 last`
mgroup=`echo $usernames| xargs -n1 groups`
echo $usernames > /var/local/nsu/logs/useraccountstatus.log
echo "$mlast" >>/var/local/nsu/logs/useraccountstatus.log
echo "$mgroup" >>/var/local/nsu/logs/useraccountstatus.log
You will want to polish this and make the output more useful.

top: counting the number of processes belonging to a user

Is there way of counting the number of processes being run by a user in the unix/linux/os x terminal?
For instance, top -u taha lists my processes. I want to be able to count these.
This will show all of the users with their counts (I believe this would be close enough for you. :)
ps -u "$(echo $(w -h | cut -d ' ' -f1 | sort -u))" o user= | sort | uniq -c | sort -rn
You can use ps to output it and count the number using wc, as:
ps -u user | sed 1d | wc -l
You can also dump top output and grep it, something like:
top -u user -n1 | grep user | wc -l
I'm somewhat new to *nix, so perhaps I did not fully understand the context of your question, but here is a possible solution:
jobs | wc -l
The output of the above command is a count of all the processes reported by the jobs command. You can manipulate the parameters of the jobs command to change which processes get reported.
EDIT: Just FYI, this would only work if interested in commands originating from a particular shell. If you want more control in looking at system-wide processes you probably want to use ps as others have suggested. However, if you use wc to do your counting, make sure you take into account any extraneous white space jobs, ps or top may have generated as that will affect the output of wc.

for loop in bash to get more than 1 variables to use it in one command [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have one text file and I need to get 2 variables from the same text and put them in one command like
for i in `cat TEXT | grep -i UID | awk '{print($2)}'` &&
x in `cat TEXT | grep -i LOGICAL | awk '{print($4)}'`
do
echo "naviseccli -h 10.1.1.37 sancopy -create -incremental -name copy_$i -srcwwn $x -destwwn xxxxxxxxxxxxxxxxxxxxxx -verify -linkbw 2048" >> OUTPUT
done
is there any possible way to accomplish that am storage admin and need to do tons of commands so i need to get this script to do it
You could make use of file descriptors. Moreover, your cat, grep, awk command could be combined into a single awk command:
exec 5< <(awk '{IGNORECASE=1}/UID/ {print $2}' TEXT)
exec 6< <(awk '{IGNORECASE=1}/LOGICAL/ {print $4}' TEXT)
while read i <&5 && read x <&6
do
echo command $i $x # Do something with i and x here!
done
Perform the cat operations first and save the result into two arrays. Then you can iterate with an index over one array and use the same index to also access the other one.
See http://tldp.org/LDP/abs/html/arrays.html about arrays in bash. Especially see the section "Example 27-5. Loading the contents of a script into an array".
With that resource you should be able to both populate your arrays and then also process them.
Since your words don't have spaces in them (by virtue of the use of awk), you could use:
paste <(grep -i UID TEXT | awk '{print($2)}') \
<(grep -i LOGICAL TEXT | awk '{print($4)}') |
while read i x
do
echo "naviseccli -h 10.1.1.37 sancopy -create -incremental -name copy_$i -srcwwn" \
"$x -destwwn xxxxxxxxxxxxxxxxxxxxxx -verify -linkbw 2048" >> OUTPUT
done
This uses Process Substitution to give paste two files which it pieces together. Each line will have two fields on it, which are read into i and x for use in the body of the loop.
Note that there is no need to use cat; you were eligible for a UUOC (Useless Use of cat) award.
Imma take a wild guess that UID and LOGICAL must be on the same line in your incoming TEXT, in which case this might actually make some sense and work:
cat TEST | awk '/LOGICAL/ && /UID/ { print $2, $4 }' | while read i x
do
echo "naviseccli -h 10.1.1.37 sancopy -create -incremental -name copy_$i -srcwwn" \
"$x -destwwn xxxxxxxxxxxxxxxxxxxxxx -verify -linkbw 2048"
done

Distribution of different shells [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
What would be the command in linux to find the
distribution of different shells used by all users?
getent passwd | awk -F: '{print $7}' | sort | uniq -c
The getent command dumps the password database. Normally that's just a file, /etc/passwd, but it can come from other sources; using getent passwd rather than just reading /etc/passwd allows for that.
If your system doesn't have the getent command, find out what your system's equivalent is (perhaps ypcat passwd if your system uses NIS), or just read the /etc/passwd file directly if you're sure the information isn't stored elsewhere.
The awk command grabs the 7th colon-delimited field from each line, which is the login shell for that account.
sort | uniq -c prints the number of occurrences of each shell. Add | sort -rn if you want the list in decreasing order of popularity.
Note carefully that this lists the login shells for all accounts on the system, many of which do not actually correspond to users. There are various ways to filter the list (typically the numeric user id, the 3rd field, starts at 1000), but none that are 100% reliable.
Run this as root ! This will give you the username and their login shell.
grep -v "nologin" /etc/passwd | awk 'BEGIN{FS=":"}{print $1,$7}'
You could cat out /etc/passwd, awk out the shell field, grep -v out anything you didn't want and then sort unique it. Like so:
cat /etc/passwd | awk -F ":" '{print $7}' | grep -v "whatever" | sort | uniq -c
On my mac (which doesn't have any "real" users) this results in
10 with no shell, 1 with /bin/sh, 70 with /usr/bin/false and 1 with /usr/sbin/uucico
Presumably on a system with actual users there'd be /bin/sh, /bin/ksh, /bin/csh and /bin/bash quantities.
It usually is just inside /etc/passwd (but as the above answer tells, is given by getent passwd); on some systems it could by a NIS/YP, LDAP, ... etc ... database (but see also pam). Details are configurable in /etc/nsswitch.conf (see nsswitch.conf(5) man page).
Also, the authorized login shells are listed in /etc/shells (see shells(5)); you need to add a shell's pathname there to make it changeable by chsh (see chsh(1)).

Resources