How do I get pipe to work when passed in string for sh -c and su is involved - sh

I have the below command
su - root -s /usr/bin/sh -c "java -version|grep build"
But the pipe to grep doesn't seem to work since it prints all lines regardless

java -version writes to standard error, not standard output.
su - root -s /usr/bin/sh -c "java -version 2>&1 |grep build"
2>&1 copies standard error to standard output, so that it gets fed through the pipe and into grep.
That said, grep doesn't have to be run as root, assuming the pipeline isn't being specified for use by something that just runs arbitrary code using su sh -c '...'.
su - root -s /usr/bin/sh -c 'java -version' 2>&1 | grep build

Related

lxc option "--" when calling lxc-start / lxc-create

What is the significance of -- in the command line of commands like lxc-create or lxc-start.
I tried to use Google in order to get an answer but without success.
// Example 1
lxc-create -t download -n u1 -- -d ubuntu -r DISTRO-SHORT-CODENAME -a amd64
// Example 1
application="/root/app.out"
start="/root/lxc-app/lxc-start"
$start -n LXC_app -d -f /etc/lxc/lxc-app/lxc-app.conf -- $application &
As explained in the references provided in the comments, the "--" indicates the end of the options passed to the command. The following parameters/options will be eventually used by a sub-command called by the command.
In your example:
lxc-create -t download -n u1 -- -d ubuntu -r DISTRO-SHORT-CODENAME -a amd64
lxc-create command will interpret "-t download -n u1" and the remaining "-d ubuntu -r DISTRO-SHORT-CODENAME -a amd64" will be passed to the template script which will configure/populate the container.
In this specific example, the "-t download" makes lxc-create run a template script named something like "/usr/share/lxc/templates/lxc-download" to which it will pass "-d ubuntu -r DISTRO-SHORT-CODENAME -a amd64".

Powershell - Run SCP command using CYGWIN but also expand variables

I need to expand variables before running the SCP command as a result I can't use single quote. If I run the script using double quotes in Powershell ISE it works fine.
But doesn't work if I run the script through command prompt.
I'm using zabbix to run the script which calls the script as [cmd /C "powershell -NoProfile -ExecutionPolicy Bypass -File .\myscript.ps1"]
Here is the code that needs to run SCP using Cygwin bash.
if ((test-path "$zipFile"))
{
C:\cygwin\bin\bash.exe -l "set -x; scp /cygdrive/e/logs/$foldername/dir1/$foldername.zip root#10.10.10.10:~/"
}
Output:
/usr/bin/bash: set -x; /cygdrive/e/logs/myfolder/dir1/server.zip root#10.10.10.10:~/: No such file or directory
If I run the same command above in Cygwin manually it works.
I even tried to use bash -l -c but then the SSH session is stuck maybe because the root#10.10.10.10 becomes $1 according to the documentation.
Documentation link
-c If the -c option is present, then commands are read from
the first non-option argument command_string. If there are
arguments after the command_string, the first argument is
assigned to $0 and any remaining arguments are assigned to
the positional parameters. The assignment to $0 sets the
name of the shell, which is used in warning and error
messages.
Figured it out. It was halting when using bash -c was due to StrictHostKeyChecking, the known hosts thing (where you get a prompt to type yes/no). I set the -v switch to SCP and it showed me the Debug logs where it was halting.
Had to set scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null options.
The complete line now looks like the following:
c:\$cygwin_folder\bin\bash.exe -c ("/usr/bin/scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -v -i /cygdrive/c/cygwin/home/myuser/.ssh/id_rsa /cygdrive/e/logs/$foldername/dir1/$foldername.zip root#10.10.10.10:~/")

Perl Returning error for ls -l command

I am running a perl script from Nagios to check some files for certain characteristics on a windows machine. When I run the script from Nagios it responds with a result of:
UNKNOWN ERROR - execution of LANG=C ls -l resulted in an error 32512 -
My Code is from this GitHub with a single modification of line 168 so I can use it with windows:
use lib 'C$\Progra~1\Nagios\NRDS_Win\plugins';
The odd thing is the program actually outputs the expected result from the command line on the windows machine.
Here is the command:
check_files.pl -D c:\logs -F Health.log -a '~,300'
Here is an example:
CRITICAL - Health.log is 10703 (more than 300) seconds old - 1
Health.log files found
I modified line that defined LANG=C ls -l in the code but now i just get:
UNKNOWN ERROR - could not execute ls -l - No such file or directory
ls is unix command and by default there is no such command in windows.
If you need it, you can install it e.g. from GNU CoreUtils
You also need to change shell command on line 639 from LANG=C ls -l to just ls -l because in windows you can't set environment variables like that.

perl run two system commands error

So in my script I need to make to calls to unix, and I do it via the system command like so:
system "bash -i -c 'addmothernode'";
...
perl code ...
...
system "bash -i -c 'addnode -ip=$_'";
However, whenever I run both of these commands in the same script, for some reason my process is stopped like this:
[1]+ Stopped perl boot.pl
And the script can only be finished when I run fg %1. When I only have one of these system calls in, the perl script finishes successfully. But I need both commands because they depend on each other. Anyone have any ideas about what's going on? Thanks!
UPDATE:
A lot of answers below are saying I don't need to use bash -i to run a system command, and I know typically this is true but I need to use aliases that I have created and if I do not use this the aliases won't be recognized. So I do need bash -i.
This problem is unrelated to perl. You can easily reproduce the situation if you start two bashes in the interactive mode (-i) one after another:
$ cat 1.sh
bash -i -c 'sleep 1'
bash -i -c 'sleep 1'
$ bash 1.sh
[1]+ Stopped bash 1.sh
Of course it would be better to run bash in the non-interactive mode (without -i) or run the program directly, without bash, but if you need for some reason bash -i you can protect its run with setsid:
$ cat 1.sh
setsid bash -i -c 'sleep 1'
setsid bash -i -c 'sleep 1'
echo done
$ bash 1.sh
done
The bash -i means run an interactive shell; so you have two shells both reading from the terminal.
Try removing the -i options.
system "addmothernode";
should work.
To execute a command, bash is not needed. The Perl system function is like the system C function, it calls by default sh.
man system
exec
The standard to which the caller conforms determines which shell is used. See standards(5).
Standard Shell Used
______________________________________________________________
1989 ANSI C, 1990 ISO C, 1999 ISO C, /usr/xpg4/bin/sh
POSIX.1 (1990-2001), SUS, SUSv2, SUSv3,
XPG4
POSIX.1 (1988), SVID3, XPG3, no standard /usr/bin/sh
specified

Varnish DAEMON_OPTS Options Errors

When using inline C with Varnish I've not been able to get /etc/varnish/default
to be happy at startup.
I've tested inline C with varnish for two things: GeoIP detection and Anti-Site-Scraping functions.
The DAEMON_OPTS always complains even though I'm following what other seem
to indicate works fine.
My problem is that this command line start up works:
varnishd -f /etc/varnish/varnish-default.conf -s file,/var/lib/varnish/varnish_storage.bin,512M -T 127.0.0.1:2000 -a 0.0.0.0:8080 -p 'cc_command=exec cc -fpic -shared -Wl,-x -L/usr/include/libmemcached/memcached.h -lmemcached -o %o %s'
But it errors out with trying to start up from default start scripts:
/etc/default/varnish has this in it:
DAEMON_OPTS="-a :8080 \
-T localhost:2000 \
-f /etc/varnish/varnish-default.conf \
-s file,/var/lib/varnish/varnish_storage.bin,512M \
-p 'cc_command=exec cc -fpic -shared -Wl,-x -L/usr/include/libmemcached/memcached.h -lmemcached -o %o %s'"
The error is:
# /etc/init.d/varnish start
Starting HTTP accelerator: varnishd failed!
storage_file: filename: /var/lib/varnish/vbox.local/varnish_storage.bin size 512 MB.
Error:
Unknown parameter "'cc_command".
If I try change the last line to:
-p cc_command='exec cc -fpic -shared -Wl,-x -L/usr/include/libmemcached/memcached.h -lmemcached -o %o %s'"
It's error is now:
# /etc/init.d/varnish start
Starting HTTP accelerator: varnishd failed!
storage_file: filename: /var/lib/varnish/vbox.local/varnish_storage.bin size 512 MB.
Error: Unknown storage method "hared"
It's trying to interpret the '-shared' as -s hared and 'hared' is not a storage type.
For both GeoIP and the Anti-Site-Scrape I've used the exact recommended daemon options
plus have tried all sorts of variations like adding ' and '' but no joy.
Here is a link to the instruction I've followed that work fine except the DAEMON_OPTS part.
http://drcarter.info/2010/04/how-fighting-against-scraping-using-varnish-vcl-inline-c-memcached/
I'm using Debian and the exact DAEMON_OPTS as stated in the instructions.
Can anyone help with a pointer on what's going wrong here?
Even if Jacob will probably never read this, visitors from the future might appreciate what I'm going to write.
I believe I know what's wrong, and it looks like a Debian-specific problem, at least verified on Ubuntu 11.04 and Debian Squeeze.
I traced the execution from my /etc/default/varnish that contains the $DAEMON_OPTS to the init script.
In the init script /etc/init.d/varnish, the start_varnishd() function is:
start_varnishd() {
log_daemon_msg "Starting $DESC" "$NAME"
output=$(/bin/tempfile -s.varnish)
if start-stop-daemon \
--start --quiet --pidfile ${PIDFILE} --exec ${DAEMON} -- \
-P ${PIDFILE} ${DAEMON_OPTS} > ${output} 2>&1; then
log_end_msg 0
else
log_end_msg 1
cat $output
exit 1
fi
rm $output
}
So I modified it to print the full start-stop-daemon command line, like:
start_varnishd() {
log_daemon_msg "Starting $DESC" "$NAME"
output=$(/bin/tempfile -s.varnish)
+ echo "start-stop-daemon --start --quiet --pidfile ${PIDFILE} --exec ${DAEMON} -- -P ${PIDFILE} ${DAEMON_OPTS} > ${output} 2>&1"
if start-stop-daemon \
--start --quiet --pidfile ${PIDFILE} --exec ${DAEMON} -- \
-P ${PIDFILE} ${DAEMON_OPTS} > ${output} 2>&1; then
log_end_msg 0
So I got a command line echoed on STDOUT, and copied-pasted it into my shell. And, surprise! It worked. WTF?
Repeated again to be sure. Yes, it works. Mmh. Could it be another of those bash/dash corner cases?
Let's try feeding the start-stop-daemon command line to bash, and see how it reacts:
start_varnishd() {
log_daemon_msg "Starting $DESC" "$NAME"
output=$(/bin/tempfile -s.varnish)
if bash -c "start-stop-daemon \
--start --quiet --pidfile ${PIDFILE} --exec ${DAEMON} -- \
-P ${PIDFILE} ${DAEMON_OPTS} > ${output} 2>&1"; then
log_end_msg 0
else
log_end_msg 1
cat $output
exit 1
fi
rm $output
}
Yes, it works just fine, at least for my case.
Here's the relevant part of my /etc/default/varnish:
...
## Alternative 2, Configuration with VCL
#
# Listen on port 6081, administration on localhost:6082, and forward to
# one content server selected by the vcl file, based on the request. Use a 1GB
# fixed-size cache file.
#
DAEMON_OPTS="-a :6081 \
-T localhost:6082 \
-f /etc/varnish/geoip-example.vcl \
-S /etc/varnish/secret \
-s malloc,100M \
-p 'cc_command=exec cc -fpic -shared -Wl,-x -L/usr/include/GeoIP.h -lGeoIP -o %o %s'"
...
I've seen posts where someone tried to work around this problem by moving the compile command into a separated shell script. Unfortunately that doesn't change the fact that start-stop-daemon is going to pass the $DAEMON_OPTS var through dash, and that will result in mangled options.
Would be something along the lines of:
-p 'cc_command=exec /etc/varnish/compile.sh %o %s'"
And then the compile.sh script as:
#!/bin/sh
cc -fpic -shared -Wl,-x -L/usr/include/GeoIP.h -lGeoIP -o $#
but it doesn't work, so just patch your init scripts, and you're good to go!
Hope you can find this information useful.
You can try using :-
DAEMON_OPTS="-a :8080 \
-T localhost:2000 \
-f /etc/varnish/varnish-default.conf \
-s file,/var/lib/varnish/varnish_storage.bin,512M \
-p cc_command='exec cc -fpic -shared -Wl,-x -L/usr/include/libmemcached/memcached.h -lmemcached -o %o %s'"
Obviously, your startup script interpreting the DAEMON_OPTS is not prepared for whitespace (even within single quotes). At my Fedora (15) installation, the suggested solution works fine; the arguments get interpreted correctly because the "$*" bash parameter is passed in /etc/init.d/varnish and in /etc/init.d/functions in daemon().
Did you get your startup scripts from a package or did you make custom scripts?
This isn't directly related to the question, but you may find yourself here if you are working through the Varnish Tutorial - Put Varnish on port 80.
For recent installs of Varnish on Debian systems the configuration for varnishd startup options can be found in /etc/systemd/system/multi-user.target.wants/varnish.service. The documented way of changing the port via /etc/default/varnish still exists, but is no longer functional unless you change your system to use init scripts rather than systemd.
After you've changed your options in /etc/systemd/system/multi-user.target.wants/varnish.service, don't forget to run systemctl daemon-reload, which will catalog the changes for executing the program.