Distribution of different shells [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
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)).

Related

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.

Is it possible to find which process is using OPENSSL in linux?

Suppose, one process is running and accessing OPENSSL shared library to perform some operation. Is there any way to find the pid of this process ?
Is there any way to find on which core this process is running ?
If possible, does it require any special privilege like sudo etc?
OS- Debian/Ubuntu
Depending on what exactly you want, something like this might do:
lsof | grep /usr/lib64/libcrypto.so | awk '{print $1, $2}' | sort -u
This essentially:
uses lsof to list all open files on the system
searches for the OpenSSL library path (which also catches versioned names like libcrypto.so.1.0)
selects the process name and PID
removes any duplicate entries
Note that this will also output processes using previous instances of the shared library file that were e.g. updated to a new version and then deleted. It also has the minor issue of outputting duplicates when a process has multiple threads with different names.
And yes, this may indeed require elevated privileges, depending on the permissions on your /proc directory.
If you really do need the processor core(s), you could try something like this (credit to dkaz):
lsof | grep /usr/lib64/libcrypto.so | awk '{print $2}' |
xargs -r ps -L --no-headers -o pid,psr,comm -p | sort -u
Adding the lwp variable to the ps command would also show the thread IDs:
lsof | grep /usr/lib64/libcrypto.so | awk '{print $2}' |
xargs -r ps -L --no-headers -o pid,lwp,psr,comm -p
PS: The what-core-are-the-users-of-this-library-on requirement still sounds a bit unusual. It might be more useful if you mentioned the problem that you are trying to solve in broader terms.
thkala is almost right. The problem is that the answer is half, since it doesn't give the core.
I would run that:
$ lsof | grep /usr/lib64/libcrypto.so |awk '{print $2}' | xargs ps -o pid,psr,comm -p

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.

Scripting with unix to get the processes run by users [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
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.

awk: Iterate through content of a large list of files [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Improve this question
So, I have about 60k-70k vCard-Files and want to check (or, at this point, count), which vCards contain a mail address (EMAIL;INTERNET:me#my-domain.com)
I tried to pass the output of find to awk, but I just get awk to work with the files list, not with every files content. How can I get awk to do so? I tried several combinations of find, xargs and awk, but I don't get it to work properly.
Thanks for your help,
Wolle
I'd probably use grep for this.
If you want to extract adresses from the files:
grep -rio "EMAIL;INTERNET:.*#[a-z0-9-]*\.[a-z]*" *
Use cut, sed or awk to remove the leading EMAIL;INTERNET::
... | cut -d: -f2
... | sed "s/.*://"
... | awk -F: '{print $2}'
If you want the names of the files containing a particular address:
grep -ril "EMAIL;INTERNET:me#my-domain\.com" *
If grep can't process that many files at once, drop the -r option and try with find and xargs:
find /start/dir -name "*.vcf" -print0 | xargs -0 -I {} grep -io "..." {}
grep recursive can do this
grep -r 'EMAIL.+#'

Resources