Grep command list bin/bash or dash - bash

Is there a grep command that lists all users (in /etc/passwd) who use either bash (/bin/bash) or dash (/bin/sh) and their home directory is in /home (second to last section of: has home directory)?
I am thinking of commands:
getent passwd | awk -F ':' '$6 ~ "^/home" {print $1}'
or :
getent passwd| awk -F ":" '$7=="/bin/bash" { print $1 }'
but I am wrong.

Just combine your conditions:
getent passwd | awk -F':' '$7 ~ "^/bin/(ba)?sh$" && $6 ~ "^/home/"{ print $1 }'
or
getent passwd | awk -F':' '($7=="/bin/bash" || $7=="/bin/sh") && $6 ~ "^/home/"{ print $1 }'

The grep command that satisfies your conditions is as follows:
getent passwd | grep -E ':/home/.*?:.*?[bd]ash$'
The regex is all the lines with a home directory and bash or dash.

Related

Running last in awk [Solaris]

How can i run last command for every matched line in awk?
ypcat passwd | awk -F":" '/:John / { system("last" $1) }'
I'm trying to execute the last command for every user that is named John but It does not print anything.
Insert a whitespace after last:
ypcat passwd | awk -F":" '/:John / {system("last " $1)}'
Your approach is wrong, awk is not shell. awk is designed to manipulate text not to call other tools from, that is what a shell is for This may be what you want, depending on what last is/does:
ypcat passwd | awk -F":" '/:John /{print $1}' | xargs last
or:
ypcat passwd | awk -F":" '/:John /{print $1}' | xargs -n 1 last

Error when awk command's parameter is being used in pattern

I'm running these commands:
ps -ef | awk -v piddd="$child_pid" '$2 ~ /\<piddd\>/ { print $3; }'
ps -ef | awk -v piddd="$child_pid" '$2 ~ /piddd/ { print $3; }'
It doesn't give me any result. When I try with this one, I get what I need, although in some cases I'll get additional pids:
ps -ef | awk -v piddd="$child_pid" '$2 ~ piddd { print $3; }'
What is wrong with first ones?
You cannot use a variable with the /pattern/ syntax.
If you want to add word boundaries (and your version of awk supports the syntax), you can do so by concatenating strings:
ps -ef | awk -v piddd="$child_pid" '$2 ~ "\\<" piddd "\\>" { print $3 }'
Note that the \ must be escaped in this case.
If you just want the whole field to match the exact variable, I'd suggest using a simple string comparison:
ps -ef | awk -v piddd="$child_pid" '$2 == piddd { print $3 }'
There isn't a need to parse the output of ps utility just to get the parent pid PPID of a child PID. The ps utility already provides this functionality.
ps -o ppid= -p $child_pid
The parameter -o ppid= tells ps to just print the parent pid. Without = the printout will contain a header PPID.
The parameter -p $child_pid tells ps to get the process information from the process id identified by variable $child_pid.
ps -ef | awk '$2 ~ /'`echo "$child_pid"`'/ { print $3; }'
# or
ps -ef | awk '$2 ~ /'$child_pid'/ { print $3; }'
# or create function
function father_pid() { ps -ef | awk '$2 ~ /'$1'/ { print $3; }'; }
# use function
father_pid $child_pid

loop passwd in shell script

how can i make a loop for users of server using shell script
i wrote this code ..
#!/bin/bash
b=`awk -F: '{ print $1 }' /etc/passwd | sort`
for $b in /home/$b/ /home/$b/ /home/$b/
echo "$b"
done
i want to loop all users and show its
the users like in file
/etc/passwd
like :
root,admin,cpanel,adm,mysql,user1,user2,user3,user4,user5
i want the output :
/home/adm
/home/root
/home/admin
/home/mysql
/home/user1
/home/user2
and thanks
To print /home/ before each user name:
$ awk -F: ' { print "/home/"$1 }' /etc/passwd | sort
/home/avahi
/home/backup
/home/bin
/home/clamav
/home/colord
/home/daemon
[...snip...]
If you want actual home directories, you can find them in field 6:
$ awk -F: ' { print $6 }' /etc/passwd | sort
/dev/null
/home/john1024
/nonexistent
/root
You can also access the sixth field using cut:
cut -d: -f6 /etc/passwd | sort
Printing multiple directories
As per the revised question in the comments:
$ awk -F: ' { p="/home/"$1; printf "%s\n%s\n%s\n",p"/www",p"/ftp",p"/etc" }' /etc/passwd | sort
/home/avahi/etc
/home/avahi/ftp
/home/avahi/www
/home/backup/etc
/home/backup/ftp
/home/backup/www
[...snip...]

Bash: copy a file to all home directories

I have to copy (overwrite if it already exists) a file to all the home directories of users members of a same group ("students").
I found a script that I tried to adapt to my context (I have LDAP users instead of /etc/passwd so I used getent passwd to fetch usernames).
Here it is the script (cp2stud.sh):
#!/bin/bash
# subdirectory of /home/uid
DIR=".eclipse/org.eclipse.platform_3.8_155965261/configuration"
# the file to copy
FILE="/home/admin/tmp/config.ini"
# location of home dirs
UHOME="/home"
# GID of "students" group
USERS_GID=10004
# get list of users having same GID
_USERS="$(getent passwd | awk -F ':' '{if ( $4 == $USERS_GID ) print $1 }')"
for u in $_USERS
do
_dir="${UHOME}/${u}/${DIR}"
if [ -d "$_dir" ]
then
yes | /bin/cp -v "$FILE" "$_dir"
chown $(id -un $u):students "$_dir/${FILE}"
fi
done
When i try to launch it:
$ sudo cp2stud.sh
I get nothing.
Where I am mistaking?
Thanks in advance
_USERS="$(getent passwd | awk -v X="$USERS_GID" -F ':' '{if ( $4 == X ) print $1 }')"
Try this approach:
...
export USERS_GID=10004
_USERS=$(getent passwd | awk -F ':' '{if ( $4 == ENVIRON["USERS_GID"] ) print $1 }')
...
You could also do something like this:
...
USERS_GID=10004
_USERS=$(getent passwd | awk -F ':' -v gid=$USERS_GID '{if ( $4 == gid ) print $1 }')
...
Or just:
...
_USERS=$(getent passwd | awk -F ':' -v gid=10004 '{if ( $4 == gid ) print $1 }')
...
The following code works:
DIR=".eclipse/org.eclipse.platform_3.8_155965261/configuration"
FILE="/home/admin/tmp/config.ini"
UHOME="/home"
USERS_GID=10004
GRP_NAME=students
FILENAME=$(basename $FILE)
_USERS="$(getent passwd | awk -v X="$USERS_GID" -F ':' '{if ( $4 == X ) print $1 }')"
for u in $_USERS
do
_dir="${UHOME}/${u}/${DIR}"
if [ -d "$_dir" ]
then
yes | /bin/cp -v "$FILE" "$_dir"
chown -v $(id -un $u):$GRP_NAME "${UHOME}/${u}/${DIR}${FILENAME}"
fi
done

How to escape grep and awk within pipe in an alias?

I want to create an alias for an long command. But I'm not able to escape it correct, I guess it's a problem with the pipes.
My original command
ps aux | grep gimp | awk '{ print $2 '\011' $11 }' | grep -v 'grep'
My attempt for an alias
alias psa="ps aux | grep $1 | awk '{ print \$2 \"\011\" \$11 }' | grep -v 'grep'"
But I get an error that grep can not open file foo (when I do psa foo)
When I remove the last part | grep -v 'grep' then awkthrows the same error.
I prefer an alias before an shell script.
You need to use a function if you want to to insert arguments:
psa() {
ps aux | grep "$1" | awk '{print $2 "\t" $11 }' | grep -v grep
}
You can avoid all the escaping by using a function for this:
myps() {
ps aux | grep gimp | awk '{ print $2 "\011" $11 }' | grep -v 'grep'
}

Resources