Why is echo showing the command itself and not the command output - linux

Why is echo showing the command and not the output of the command once I start using it in a FOR I loop? For example this command works
root#linux1 tmp]# iscsiadm -m node |awk '{print $1}'
192.168.100.88:326
But not in a FOR I loop
[root#linux1 tmp]# for i in 'iscsiadm -m node | awk '{print $1}'';do echo $i;done
iscsiadm -m node | awk {print
}
I want the command to print the first field so then I can add other functionality to the For I loop. Thanks
EDIT -- Not sure why I got voted down on this question. Please advise.

You're not executing the iscsiadm and awk commands, because you quoted it; that makes it a literal string. To substitute the output of a command back into the command line, use $(...)
for i in $(iscsiadm -m node |awk '{print $1}'); do
echo $i
done

Related

Display the name of all running processes in Linux in a file using a bash script

I need to display the name of all running processes in Linux in a file using a bash script. I wrote the code, but didnt succeed:
#!/bin/bash
for i in `ps aux| awk '{print $5}'`;
echo $i > /tmp/test;
done
Need your assistance, Thanks.
Using the for, the syntax is slightly different:
#!/bin/sh
cat /dev/null > /tmp/test
for i in $(ps aux | awk '{print $5}'); do
echo $i >> /tmp/test;
done
You missed the do operator
The output redirector > on a loop should change to appending >>, otherwise only the last value of the loop will be saved.
But as #stark said, the for is not required:
#!/bin/sh
ps aux | awk '{print $5}' > /tmp/test;
I'm not sure, what your output should look like. With your template, and the fixes from Glauco Leme, I only got the VSZ of all the processes.
I assume you need the cmd of each process, then you just can use ps -e --no-headers --format cmd.
In case you need it in a file:
ps -e --no-headers --format cmd > /tmp/test
I hope this will do what you need.

linux bash and grep bug?

Doing the following:
First console
touch /tmp/test
Second console
tail -f /tmp/test |grep propo |grep -v miles
Third console
echo propo >> /tmp/test
Second console must show "propo" but it doesn't shows anything, if you run in second console instead:
tail -f /tmp/test |grep propo
And do echo propo >> /tmp/test it will show propo, but the grep -v is for miles not for propo
Why?
Test into your own environment if you want, it's pretty obvious but not working.
Why?
Most probably because the output of a command when piped to another command is fully buffered, not line buffered. The output could be buffered in the first pipe or by grep.
Use stdbuf -oL to force line buffering and grep --line-buffered for line buffered grep.
the problem is that grep does not use line buffering by default; so the output will be buffered. You could use grep --line-buffered:
tail -f /tmp/test | grep --line-buffered propo | grep -v miles

How does this line of code work in shell?

I got confused about this line of code, could anyone explain how this code work? I can understand that its using a pipeline, but codes in the middle confuses me.
for pid in $(ps -e -f | grep $1 | grep -v $0 | awk '{print $2}')"
Check below details to understand the command, full command will be like this-
cat script.sh
for pid in $(ps -e -f | grep $1 |grep -v $0 | awk '{print $2}')
do
kill -9 $pid
done
You need to execute it like below -
./script.sh vipin
step1 : ps -e -f (will print all the processes running in the server)
step2 : ps -e -f|grep $1 (considering $1 is variable for current user,
in my case is vipin(user) which i will pass with script,so step2
will filter all the process for that user.
step3 : And $0 is the script name (script.sh), which you don't want to kill
that is why you are using grep -v(to exclude)
step4 : awk '{print $2}' to fetch only the process number.

How do I get "awk" to work correctly within a "su -c" command?

I'm running a script at the end of a Jenkins build to restart Tomcat. Tomcat's shutdown.sh script is widely known not to work all in many instances and so my script is supposed to capture the PID of the Tomcat process and then attempt to manually shut it down. Here is the command I'm using to capture the PID:
ps -ef | grep Bootstrap | grep -v grep | awk '{print $2}' > tomcat.pid
The output when manually runs retrieves the PID perfectly. During the Jenkins build I have to switch users to run the command. I'm using "su user -c 'commands'" like this:
su user -c "ps -ef | grep Bootstrap | grep -v grep | awk '{print $2}' > tomcat.pid"
Whenever I do this however, the "awk" portion doesn't seem to be working. Instead of just retrieving the PID, it's capturing the entire process information. Why is this? How can I fix the command?
The issue is that $2 is being processed by the original shell before being sent to the new user. Since the value of $2 in the shell is blank, the awk command at the target shell essentially becomes awk {print }. To fix it, you just escape the $2:
su user -c "pushd $TOMCAT_HOME;ps -ef | grep Bootstrap | grep -v grep | awk '{print \$2}' > $TOMCAT_HOME/bin/tomcat.pid"
Note that you want the $TOMCAT_HOME to be processed by the original shell so that it's value is set properly.
You don't need the pushd command as you can replace the awk command with:
cut -d\ -f2
Note: two 2 spaces between -d\ and -f2

Getting PID of process in Shell Script

I am writing one shell script and I want to get PID of one process with name as "ABCD". What i did was :
process_id=`/bin/ps -fu $USER|grep "ABCD"|awk '{print $2}'`
This gets PID of two processes i.e. of process ABCD and the GREP command itself what if I don't want to get PID of GREP executed and I want PID only of ABCD process?
Please suggest.
Just grep away grep itself!
process_id=`/bin/ps -fu $USER| grep "ABCD" | grep -v "grep" | awk '{print $2}'`
Have you tried to use pidof ABCD ?
It's very straight forward. ABCD should be replaced by your process name.
#!/bin/bash
processId=$(ps -ef | grep 'ABCD' | grep -v 'grep' | awk '{ printf $2 }')
echo $processId
Sometimes you need to replace ABCD by software name. Example - if you run a java program like java -jar TestJar.jar & then you need to replace ABCD by TestJar.jar.
ps has an option for that:
process_id=`/bin/ps -C ABCD -o pid=`
You can also do away with grep and use only awk.
Use awk's expression matching to match the process name but not itself.
/bin/ps -fu $USER | awk '/ABCD/ && !/awk/ {print $2}'
You can use this command to grep the pid of a particular process & echo $b to print pid of any running process:
b=`ps -ef | grep [A]BCD | awk '{ printf $2 }'`
echo $b
ps | pgrep ABCD
You can try the above command to return the process id of the ABCD process.
I found a better way to do this.
top -n 1 | grep "##" | grep -Eo '^[^ ]+'

Resources