Unable to use grep for a command and excecute the shell script? - linux

I have created a shell script to execute 5 commands from a file called elist.txt
ps -ef | grep user | grep 'process -s 9000' | cut -c -15 | cut -c 10-
ps -ef | grep user | grep 'process -s 9001' | cut -c -15 | cut -c 10-
ps -ef | grep user | grep 'process -s 9002' | cut -c -15 | cut -c 10-
ps -ef | grep user | grep 'process -s 9003' | cut -c -15 | cut -c 10-
The shell script is as follows
export PATH="/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/user/.local/bin:/home/user/bin"
input="/home/user/script/list.txt"
while IFS= read -r line
do
echo $($line)
done < "$input"
output:
error: garbage option
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
For more details see ps(1).

You can do this too. People usually do not recommend to use eval at all.
export PATH="/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/user/.local/bin:/home/user/bin"
input="/home/user/script/list.txt"
while IFS= read -r line
do
bash -c "$line"
done < "$input"
Regards!

I would use this script with eval which is a similar solution described in this answer https://stackoverflow.com/a/6002329/6778826
export PATH="/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/user/.local/bin:/home/user/bin"
input="/home/user/script/list.txt"
while read -r line
do
eval "$line"
done <$input

Related

Troubles Executing GREP/CUT Command from Bash Script

I am trying to execute the following command in a Bash script:
grep 1001 -w /etc/passwd | cut -d ':' -f 1,4,5
grep 1004 -w /etc/passwd | cut -d ':' -f 1,4,5
it works fine from the command line in Linux, and if I remove the latter portion of the pipeline it executes properly from Bash as well.
here is my script thus far:
#/bin/bash
#find the group number correlated to reader and user
reader=`grep reader /etc/group | cut -d ":" -f3`
user=`grep user /etc/group | cut -d ":" -f3`
echo reader: $reader #prints 1004
echo user: $user #prints 1001
cmdRead="grep ${reader} -w /etc/passwd | cut -d \":\" -f 1,4,5"
cmdUser="grep ${user} -w /etc/passwd | cut -d \":\" -f 1,4,5"
echo executing command: ${cmdRead}
echo `${cmdRead}`
echo executing command: ${cmdUser}
echo `${cmdUser}`
the output of this code yields:
reader: 1004
user: 1001
executing command: grep 1004 -w /etc/passwd | cut -d ":" -f 1,4,5
grep: invalid argument ‘":"’ for ‘--directories’
Valid arguments are:
- ‘read’
- ‘recurse’
- ‘skip’
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
executing command: grep 1001 -w /etc/passwd | cut -d ":" -f 1,4,5
grep: invalid argument ‘":"’ for ‘--directories’
Valid arguments are:
- ‘read’
- ‘recurse’
- ‘skip’
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
I only started learning Bash yesterday so I apologize for the noob-esque question but greatly appreciate any help :)
Enclose your command in $( ... ), not quotes. Also, no need to quote the colon as the value of the -f parameter in cut, therefore no need to escape the quotes:
cmdRead=$(grep ${reader} -w /etc/passwd | cut -d: -f 1,4,5)

Linux use grep command

I know use ps -ef | grep test| grep -v grep |wc -l can list the num of process test,and now i plan to list the test processes belong to user :forme.is this right as below :
ps -ef | grep test|grep -x forme| grep -v grep |wc -l
For a start, grep test| grep -v grep can be replaced with grep '[t]est'. See here for an explanation.
Secondly, if you want to limit the processes to a single user, that's what the -u option to ps is for:
ps -fu forme | grep '[t]est' | wc -l
And, finally, grep already has a -c option to count lines, so you can ditch the wc part of the pipeline:
ps -fu forme | grep -c '[t]est'

How to continue executing the next other commands after using "kill" in shell?

I want to merge two different script files into one script file which could do what the two different files do. And the script files is:
script file A:
pid=`ps -ef | grep temp_tool | grep -v grep | awk '{print $2}'`
kill -9 ${pid}
script file B:
nohup ./temp_tool &
the merged script file:
pid=`ps -ef | grep temp_tool | grep -v grep | awk '{print $2}'`
kill -9 ${pid}
nohup ./temp_tool &
The whole merged script file would stop after executing kill command, and I have to modify it to be:
pid=`ps -ef | grep temp_tool | grep -v grep | awk '{print $2}'`
out=`kill -9 ${pid}`
nohup ./temp_tool &
and it works well now, but I don't know why? Is there any difference?
I would say $pid also contains the pid of your script. You can filter it out:
script_pid=$$
pid=$(ps -ef | grep temp_tool | grep -Ev "grep|$script_pid" | awk '{print $2}')
Though if you want the pids of the command temp_tool I would suggest this:
ps -C temp_tool -o pid
Instead of the ps -ef | grep ...

Groovy process not working with linux shell (grep and awk and ps)

Process proc1 ='sh -c ps -ef'.execute();
Process proc2 ='sh -c grep sleep.sh '.execute();
Process proc3 ='sh -c grep -v grep '.execute();
Process proc4 ='sh -c awk sleep.sh '.execute();
Process all = proc1 | proc2 | proc3 | proc4;
// I tried this too and this didnt work
//println( [ 'sh', '-c', 'ps -ef | grep "sleep.sh" | grep -v "grep" | awk "sleep.groovy" ' ].execute().text )
//also tried without the awk
println all.text;
Okay so what I am trying to do is ps the shell script i made (sleep.sh) [all it does it sleep for a period of time]. Not quite sure how to do that. This was my best guess^^
result:
-sh-3.2$ ./callGroovy.sh testSleep.groovy
-sh-3.2$
doesnt print anything out and doesnt give me anything (callGroovy is a shell script i use to call my groovy script)
If i run the piped commands they work still except the awk
I think i am doing the awk wrong
heres the rest piped
-sh-3.2$ ps -ef | grep "sleep.sh" | grep -v "grep"
wasadmin ***** ***** 0 **:** pts/1 **:**:** /bin/bash ./sleep.sh
(where all the * are numbers)
when i try the script with just the grep and ps it doesnt give me this output either. any suggestions? ..PS Also I tried with and without the quotes in the groovy script. Didnt think it would make a difference but worth a shot
The shell -c option expects one parameter only. Try this from the command line, and you'll see it fails as well:
sh -c ps -ef | sh -c grep sleep.sh | sh -c grep -v grep | sh -c awk sleep.sh
It needs quotes to work properly:
sh -c "ps -ef" | sh -c "grep sleep.sh" | sh -c "grep -v grep" | sh -c "awk sleep.sh"
You can quote the commands properly by starting with a list of strings instead of a string: proc1 = ['sh', '-c', 'ps -ef']. In this case you're doing the filtering in groovy, so the simple solution is to simply not invoke the commands through the shell. Try this:
Process proc1 ='ps -ef'.execute()
Process proc2 ='grep sleep.sh '.execute()
Process proc3 ='grep -v grep '.execute()
Process proc4 ='awk sleep.sh '.execute()
Process all = proc1 | proc2 | proc3 | proc4
println all.text
Finally, if things don't work properly, it can be helpful to read the stderr stream with
println all.err.text

Killing a process

I have a for loop to get the list of PID's and kill each PID. I want to display the entire line of PS output and write it to the /tmp/outfile . But from each line of PS output each field(PID,PPID,...) is written along with a new line in the /tmp/outfile. So if PS output has three lines as output i want to log these three lines into /tmp/outfile but it's breaking each field in the line and adding a new line. how can i do it.
for list in `ps -ef | grep "${process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep`
do
echo "$list" >> $CUSTOM_TMP/test5566
PID=`echo $list | awk '{print $2}'`
kill -TERM "$list"
done
Your for loop does not iterate the lines but each individual field.
Also your kill command was slightly wrong.
Just change your code to something like:
ps -ef | grep "${process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep | while read list
do
echo "$list" >> $CUSTOM_TMP/test5566
PID=`echo $list | awk '{print $2}'`
kill -TERM "$PID"
done
Isn't it easier to use the killall command for what you are trying to do?
No need for a loop at all. And this uses tee to write your temp file.
list=$(ps -ef | grep "${process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep | tee $CUSTOM_TMP/test5566 | awk '{printf "%s ", $2')
kill -TERM $list
You want to run ps before looping:
ps -ef | grep $"{process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep > $CUSTOM_TMP/test5566 2>/dev/null
for PID in `cat $CUSTOM_TMP/test5566 | awk '{print $2}'`; do
kill -TERM $PID
done
rm -f $CUSTOM_TMP/test5566
I would also insert some sanity, possibly using wc to make sure the file actually got some data from ps.
Just move the awk part to the top line, otherwise your code is fine.
for list in `ps -ef | grep "${process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep | awk '{print $2}`
do
echo "$list" >> $CUSTOM_TMP/test5566
PID=`echo $list`
kill -TERM "$list"
done
For a one liner - if your system has pgrep --
pgrep -d ' ' ${process_name} > kill.log && kill -TERM $(< kill.log)

Resources