How to pipe into grep using backticks in Linux shell script? - sh

I am trying to execute, what I thought would be, a simple shell command within a script. When I execute this from the command prompt, it works well:
$ sudo cat /etc/sysconfig/network-scripts/ifcfg-en0 | grep "IPADDR"
IPADDR=192.168.1.10
However, if I put this into a shell script:
#!/usr/bin/sh
my_command=`sudo cat /etc/sysconfig/network-scripts/ifcfg-en0 | grep "IPADDR"`
${my_command}
echo $?
I get this error:
$ sudo ./myscript.sh
./myscript.sh: line 3: IPADDR=192.168.1.10: command not found
So, how can I successfully execute this line within my shell script?
Thanks!

The problem in your case is that you are executing the result of the command...
This line executes the code as it's between "``" that are special characters for executing the given string as a command:
my_command=`sudo cat /etc/sysconfig/network-scripts/ifcfg-en0 | grep "IPADDR"`
as a result, $my_command is "IPADDR=192.168.1.10"
Then you are trying to execute it for the second time:
${my_command}
Thats why you are getting this error. There is no such a command as "IPADDR=192.168.1.10".
Just use $my_command as a result that contains your desired grepped part and skip the ${my_command} line:
#!/usr/bin/sh
my_command=`sudo cat /etc/sysconfig/network-scripts/ifcfg-en0 | grep "IPADDR"`
echo $my_command

Related

How to execute this command in systemd servicefile?

Ok, so I have this command that turns off my touchscreen. It works when I execute it in a root shell.
So this works:
sudo su
/usr/bin/echo $(ls /sys/bus/hid/drivers/hid-multitouch | awk NR==1'{print $1}') > /sys/bus/hid/drivers/hid-multitouch/unbind
And then my touchscreen stops working, which is the result that I wanted.
Now I want to make a touchscreen.service file to execute this on every boot. So in the service file I include:
ExecStart=/usr/bin/echo $(ls /sys/bus/hid/drivers/hid-multitouch | awk NR==1'{print $1}') > /sys/bus/hid/drivers/hid-multitouch/unbind
However it isn't working > nor throwing any errors that I've been able to catch.
I do know from earlier fidlings with .service files that I might actually need to use /usr/bin/sh -c, so I have also tried:
ExecStart=/usr/bin/sh -c "/usr/bin/echo $(ls /sys/bus/hid/drivers/hid-multitouch | awk NR==1'{print $1}') > /sys/bus/hid/drivers/hid-multitouch/unbind"
Yet this also doesn't work.. maybe because of the awk NR==1'{print $1}'part? I have also tried replacing it with awk NR==1'\''{print $1}'\''but again it fails to work.
Does anyone have any ideas on how to get the command that is working in my root cli environment to also work as a systemd service?
To start with,
The syntax of the awk command is just wrong. The quotes are incorrectly placed. The part NR == 1 is part of the awk command to indicate the first line record in the file, i.e.
awk NR==1'{print $1}'
# ^^^^^^^ should be within quotes
awk 'NR == 1 { print $1 }'
Your sequence of echo, ls and the command substitution $(..) doesn't look right. You are effectively echo-ing the literal string /sys/bus/hid/drivers/hid-multitouch (if ls finds the file at that path) over to the pipe and awk just writes that to the /sys/bus/hid/drivers/hid-multitouch/unbind file which might not be your desired action. You just needed to do run the command on the file directly as
awk 'NR == 1 { print $1 }' /sys/bus/hid/drivers/hid-multitouch > /sys/bus/hid/drivers/hid-multitouch/unbind
Now that, that the awk command is fixed, you have two options to run the above command as part of systemd, either put your command in a script or run the command directly. For putting it in a script refer to the Unix.SE answer Where do I put scripts executed by systemd units?. As for running the command directly in ExecStart. Aside from using /bin/sh also use the path /bin/awk
So putting it together and using /bin/ over /usr/bin, you can do below. This command uses ".." over awk script and needs escape of $1
ExecStart=/bin/sh -c '/bin/awk "NR == 1 { print \$1 }" /sys/bus/hid/drivers/hid-multitouch > /sys/bus/hid/drivers/hid-multitouch/unbind'

Piping to awk fails to output from Swift 2.0

I'm trying to run the following command to process the output via Swift 2.0 but I'm having trouble doing so.
netstat -w1 -I en | awk '{ print $3 }'
The command runs as expected when ran manually from the terminal.
I tried the method of calling /bin/sh -c with the full command as an argument but that doesn't output anything. (Similar to https://stackoverflow.com/a/29549342/2110967).
I also tried to pass the data over stdout/stdin from the netstat to the awk but didn't have much luck.
I also tried placing the code into a .sh file and running from there but again the output was never returned.

using here document and pipeline of sh at the same time

I'm using here document of sh to run some commands. now I want to parse the output of those commands using awk. However, everytime I execute it, I get the output of the command append with something like this "% No such child process"
This is how my script looks like.
#!/bin/sh
com = "sudo -u username /path/of/file -l"
$com <<EOF | awk '{print $0}'
Commands.
.
.
.
EOF
How am I going to use heredoc and pipeline without appending that unwanted string?
Thanks
Your variable assignment is wrong in a couple of ways. First, you aren't actually assigning a variable; you're trying to run a command named com whose arguments are = and a string "sudo ...". Spaces must not be used on either side of the =:
com="sudo ..."
Second, command lines should not be stored in a variable; the shell's parser can only make that work they way you intend for very simple commands. Type the command out in full, or use a shell function.
com () {
sudo -u username /path/to/file -l
}
com <<EOF | awk '{print $0}'
...
EOF
There's no problem, check :
$ cat <<EOF | awk '{print $1}'
a b c
1 2 3
EOF
a
1

Simultaneous pipe to grep and redirect to stdout

In Linux bash, I am trying to run a command and grep for an argument:
command | grep
However, I need to redirect the result of the commad to the stdout and simultaneously pipe it to grep (I need to see both the grep result and the command result in stdout).
I googled a bit and tried some variations, such as:
command | tee /dev/tty | grep
But, no luck.
I don't want to use sth like
command
command | grep
as it is ugly :)
Thanks,
Try
command | tee >(grep whatever)
Note that there's no space between these two symbols: >(.

Command not running fron cron

I have a perl script which runs successfully from the root cron on my redhat server.
However, I have added a command to the perl script to execute an ldapsearch and when running the perl script from the command line it works perfectly, yet running from cron, the ldapseach command does not work.
I've the the full path to the ldapsearch executable and I have tried using both system and exec before the ldapsearch command, but no good.
The line in the perl code does the ldap search for container room, greps the specific line in the results, then parses the data and cuts the 1st two characters of the results. The code is:
$userRoom = `exec /usr/local/bin/ldapsearch -h myldap.domain.com '(cn=$user)' room | /bin/grep -i room | /bin/grep -iv internal | /bin/cut -d'=' -f2 | /bin/cut -c 1-2`;
I'm assuming it's an evironment or permissions thing. I just can't find the right answer.
Any suggestions greatly appreciated.