ruby - construct escaped command in code - ruby

I have the following command I execute via the windows 10 command prompt which works
C:>someapp.exe -n "conf:conf_abc:\"Acc 0 (ABC=234)\",\"ABC-DEF.GH.IJKL\",\"0\",\"\",\"0\",\"\"" -b input_file.abc -P vxyz > output_temp.def
I want to use this in Ruby code as a string command and execute it via system(command).
I do the following
command = "someapp.exe -n "conf:conf_abc:\"Acc 0 (ABC=234)\",\"ABC-DEF.GH.IJKL\",\"0\",\"\",\"0\",\"\"" -b input_file.abc -P vxyz > output_temp.def"
system(command)
This gives me error syntax error, unexpected tIDENTIFIER, expecting end-of-input
How do I go about formatting the command that works in command prompt to work within Ruby ?

Use %q sigil to prevent a string interpolation:
command = %q|someapp.exe -n "conf:conf_abc:\"Acc...|
system(command)

Related

Single quotes escaping Ruby

So, Im working with a Ruby script that needs to connect to a bunch of servers and get information from them. The problem I am having is that the single quotes seem to be getting lost somehow. What am I doing wrong here ?
command = "grep -E \'^(upstream| *server)\' /etc/nginx/upstreams.conf | sed -E \'s/_pool.*//g ; s/^upstream //g\'"
puts system("ssh -n -o 'StrictHostKeyChecking no' #{nginx_stage_servers[0]} #{command}")
Error I am getting :
$ ruby nx.rb
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `grep -E ^(upstream| *server) /etc/nginx/upstreams.conf'
true
The reason of the error is the single quotes missing.
You have too many layers of quoting and escaping to deal with when you use system(command_string), you're almost always better off using the multi-argument form of Kernel#system to avoid dealing with the shell. Something like this will be less problematic:
system('ssh', '-n', '-o', 'StrictHostKeyChecking no', nginx_stage_servers[0], command)

How do I execute a sed command from a Bash variable?

I have a sed command that works when executed directly.
echo foo > /home/user/bar
sed -i 's/foo/zoo/' /home/user/bar
It also works when directly embedded in $(...) or `...`.
However, if I try to execute it from a Bash variable, I get an error:
CMD="sed -i 's/foo/zoo/' /home/user/bar"
$CMD
Error:
sed: -e expression #1, char 1: unknown command: `''
It also works if I echo it out and source the file:
echo $CMD > file
source file
What's going on here, and how do I get the sed command to run from a Bash variable?
Don't store full command a string variable to avoid word splitting. Use an array or shell function:
# store command in an array
cmd=(sed -i 's/foo/zoo/' /home/user/bar)
# execute the command
"${cmd[#]}"
Or else use a shell function:
fn() {
sed -i 's/foo/zoo/' /home/user/bar
}
#call it as:
fn
Read this BASH FAQ: I'm trying to put a command in a variable, but the complex cases always fail!
use eval : I am not sure why you want to do it. Note that using eval is a fragil solution and can cause your script to broke.
eval $CMD

String interpolation while running shell command through ruby?

Struggling with string interpolation while executing a shell command in ruby. Can you someone please help me identify what I'm missing here?
My one-liner ruby code follows redirects of any shortURL and returns the final URL. For example, this ruby code works perfectly fine.
curl -I https://bit.ly/1mJk8X7 | perl -n -e '/^Location: (.*)$/ && print "$1\n"'
It prints out the final URL.
I have a .txt file with a series of short URLs from which I'd like to derive a list of the final URLs. Say, it's called shortURLs.txt. I'm using IO.foreach to loop through each line in the file, but I don't know what I'm doing wrong to bring the variable 'x' into the ruby command. This is my first time working with string interpolation, and I've tried various combinations of it, but no luck yet.
IO.foreach("shortURLs.txt") { |x| system "curl -I #{x} | perl -n -e '/^Location: (.*)$/ && print \"$1\n\"' >> finalURLs.txt" }
I get an error message around the pipe '|' symbol:
sh: -c: line 1: syntax error near unexpected token|'
sh: -c: line 1: | perl -n -e '/^Location: (.*)$/ && print "https://bit.ly/1mJk8X7'
Other threads have been useful about string interpolation and running shell commands through ruby.
In order to pass two commands to a shell, you should run the system command twice (check method 8 in this post)
require 'shell'
sh = Shell.new
IO.foreach("shortURLs.txt") { |x| sh.system("curl -I #{x}") | sh.system("perl -n -e '/^Location: (.*)$/ && print \"$1\n\" ' ") >> "finalURLs.txt" }
IO.foreach yields the lines including the new line at the end so you're actually executing
curl -I https://bit.ly/1mJk8X7
| perl -n -e ...
Which is why you get the syntax error. You could use strip to remove the new line from. I think the \n in the call to print will also get substituted before the string is passed to system. You may be interested in shellwords which has functions for escaping strings before passing them to a shell.
You could of course dodge the issue entirely and use ruby to get the redirect locations
require 'net/http'
require 'uri'
IO.foreach("shortURLs.txt") do |url|
puts Net::HTTP.get_response(URI.parse(url))["Location"]
end

ruby backticks redirection error

whenever I try
irb(main):008:0> `while read FILENAME; do echo "Hi";done < <(cat /tmp/a)`
I get the following error:
sh: 1: Syntax error: redirection unexpected
Is there anyway to bypass this issue, but still use back ticks for the shell exec from ruby?

condor: unmatched quotes when submitting bash jobs

I wrote a conder script for a job and use condor_submit to submit this job. Below is my script:
Executable=/bin/bash
Arguments=" -c "" command_to_run -d -f"" "
initialdir= /path/
output=/path/out
error=/path/err
log=/path/log
universe = vanilla
Getenv = true
Queue
As seen above, the executable is bash and I use -c to pass the command as a string to bash. The job gets submitted fine, but I get the following error message in err output file:
command_to_run: -c: line 0: unexpected EOF while looking for matching `"'
command_to_run: -c: line 1: syntax error: unexpected end of file
This is simply bash complaining about unmatched double quotes. But double quotes look fine to me. I don't know what the problem is. It seems like it is a condor problem. Any ideas?
If you're just passing -c to bash then single quoting should be sufficient (unless you're trying to embed variables):
Arguments=" -c 'command_to_run -d -f' "

Resources