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)
Related
I try to run bash scripts in Docker, buit I keep getting this error:
./scripts/proto-generator.sh: line 13: syntax error: unexpected "(" (expecting "then")
Here's my proto-generator.sh file:
function printGreen() {
printf "\e[0;32m$1\e[0;m\n"
}
function printRed() {
printf "\e[0;31m$1\e[0;m\n"
}
service=$1
outDir=./src/services/$service/models
protoDir=./protos/"${service}Service"/*.proto
if ! [[ "$service" =~ ^(file|user)$ ]]; then
printRed "Incorrect service: $service"
exit 1
fi
./node_modules/.bin/proto-loader-gen-types \
--longs=String \
--enums=String \
--defaults \
--oneofs \
--grpcLib=#grpc/grpc-js \
--outDir=$outDir \
$protoDir
printGreen "GRPC codes generated: ${outDir}"
How can I fix the syntax error?
Thanks for any help!!
I would have loved to ask that question as a comment, but I'm not allowed to, yet. Anyway, after having had a quick test, I assume your docker image is Alpine Linux-based. The standard Alpine Linux docker images do not come with a bash as you might be expecting but with an ash and ash does not have a [[-built in command, i.e. you should be sticking to the standard [ aka test command or get goind completely without it. And, sadly enough, test does not have the ability to handle regular expressions.
That said and again assuming that you do not want to bloat the Alpine image with a complete bash, grep comes to the rescue. A solution for your case would be (lines 13, ff.)
if ! echo $service | grep -qE "^(file|user)$" ; then
printRed "Incorrect service: $service"
exit 1
fi
explanation
Make the if directly test the return code from grep using your pattern. grep returns non-zero if there was no match, 0 otherwise. -q suppresses output of the match, -E switches to extended regular expression, as needed for the |.
Just put a
#!/bin/bash
at the top of the script
I think you are executing it in /bin/sh,
and sh doesn't support bash regex.
Or you are using an outdated version of bash, regex in bash where introduced recently.
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
I have a bash resource which is failing when attempting to loop through some ddl scripts. The same syntax without a for loop (and literal script name) works fine in Chef, and it all works including with the for loop in a terminal:
bash "run_ddl_create_tenants" do
user "#{ENV['CHEFUSER']}"
environment "PATH" => "/usr/lib/oracle/12.1/client64/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/opt/aws/bin:/home/#{ENV['CHEFUSER']}/bin"
code <<-EOH
for f in $(grep '>' /tmp/diffs/tnntdiff | cut -c 3-); do
sqlplus "admin/password#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$(aws rds describe-db-instances --db-instance-identifier #{ENV['CLIENTID']}-#{ENV['CTCENV']} | grep 'Address' | cut -d\\\" -f4))(PORT=#{ENV['DBPORT']}))(CONNECT_DATA=(SID=#{ENV['CLIENTID']}#{ENV['CTCENV']})))" <<-SQLEOH
##{ENV['CTC_CONFIGURATION']}/ddl/ddl_create_tenant_$f.sql
#{ENV['DBPASSWD']}
exit;
SQLEOH
done
EOH
end
The errors I am getting indicate a problem with the SQLEOH delimiter and unexpected end-of-file.
STDERR: /tmp/chef-script20151012-25490-16o11q7: line 7: warning: here-document at line 2 delimited by end-of-file (wanted `SQLEOH')
/tmp/chef-script20151012-25490-16o11q7: line 8: syntax error: unexpected end of file
What is the disconnection between the terminal commands and the way Chef is interpreting this resource?
Got it, issue of whitespaces preceding the delimiter. Removed indentation on SQLEOH and connected successfully
In a Makefile, I need to cycle through a list and write the current element of the list in a file.
The code is the following:
SHELL := /bin/bash
LIST = A B C
test:
for i in $(LIST) do \
echo $ii > file.txt \
done
I get the following error:
/bin/bash: -c: line 1: syntax error near unexpected token `>'
Do you know how to fix it?
You are missing a ; after $(LIST). You need to terminate the list of words you are giving to for before you can start the do block.
As indicated in the comments, you additionally need a : at the end of the echo line (the command that gets run has no newlines the way this works at the normal command line so you need to explicitly separate the commands from each other).
And further, to get the results you expect, you need to escape the $ in the shell command by using $$i (also pick one of $i or $ii as your variable name).
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' "