CHEF Scipt with embedded BASH/SED command: unexpected `}' - bash

Trying to execute SED against a file from chef is yielding an error, that I am having trouble tracking down
It runs without issue from the console:
sed -i.bak -e "\$aolcRootPW: {SSHA}Z/+CHVP/Vx3bA2m6l0aI6uvIMhJUitpT" /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif
However from my recipe:
bash 'UPDATE /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif #3' do
code <<-EOH
sed -i.bak -e "\$aolcRootPW: {SSHA}Z/+CHVP/Vx3bA2m6l0aI6uvIMhJUitpT" /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif
EOH
end
I am getting the following error
================================================================================
Error executing action `run` on resource 'bash[UPDATE /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif #3]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '1'
---- Begin output of "bash" "/tmp/chef-script20151029-7070-y3iz58" ----
STDOUT:
STDERR: sed: -e expression #1, char 8: unexpected `}'
---- End output of "bash" "/tmp/chef-script20151029-7070-y3iz58" ----
Ran "bash" "/tmp/chef-script20151029-7070-y3iz58" returned 1
Resource Declaration:
---------------------
# In /var/chef/cache/cookbooks/3rd-open-ldap-server/recipes/default.rb
64: bash 'UPDATE /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif #3' do
65: code <<-EOH
66: sed -i.bak -e "\$aolcRootPW: {SSHA}Z/+CHVP/Vx3bA2m6l0aI6uvIMhJUitpT" /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif
67: EOH
68: end
69: bash 'UPDATE /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif #4' do
Compiled Resource:
------------------
# Declared in /var/chef/cache/cookbooks/3rd-open-ldap-server/recipes/default.rb:64:in `from_file'
bash("UPDATE /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif #3") do
action [:run]
retries 0
retry_delay 2
default_guard_interpreter :default
command "UPDATE /etc/openldap/slapd.d/cn\\=config/olcDatabase\\=\\{2\\}bdb.ldif #3"
backup 5
returns 0
code " sed -i.bak -e \"$aolcRootPW: {SSHA}Z/+CHVP/Vx3bA2m6l0aI6uvIMhJUitpT\" /etc/openldap/slapd.d/cn=config/olcDatabase={2}bdb.ldif\n"
interpreter "bash"
declared_type :bash
cookbook_name "3rd-open-ldap-server"
recipe_name "default"
end
Confusingly I don't know what character 8 is. I suspect that it is some sort of escaping issue - but I have no idea where.
Update (to provide insight to where it is not): I think it is in the sed command and not the file name as this command works without issue from chef:
bash 'UPDATE /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif #2' do
code <<-EOH
sudo sed -i.bak s/dc=my-domain,dc=com/dc=my,dc=lan/g /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif
EOH
end

I suspect the problem is that there is some environment being set up when you wrap the command where the $a... is getting some bogus shell var substitution done on it. What if you just use single quotes and ditch the \ to try to prevent any such thing?
I.e.:
bash 'UPDATE /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif #3' do
code <<-EOH
sed -i.bak -e '$aolcRootPW: {SSHA}Z/+CHVP/Vx3bA2m6l0aI6uvIMhJUitpT' /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif
EOH
end

I needed to double escape the $ at the start of the sed expression:
bash 'UPDATE /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif #3' do
code <<-EOH
sed -i.bak -e "\\$aolcRootPW: {SSHA}Z/+CHVP/Vx3bA2m6l0aI6uvIMhJUitpT" /etc/openldap/slapd.d/cn\=config/olcDatabase\=\{2\}bdb.ldif
EOH
end

Related

Syntax error: end of file unexpected (expecting "fi"))

I have the below shell script.
#!/bin/sh
i=1
for label in 'Mod Name' 'Issue No' 'UT Status' 'Dev ID' 'Loc'; do
if ! grep -q "^ $((i++)). $label:" $1; then
cat <<- EOF
Proposed message does not satisfy this repository's exacting standards
It must match the template:
1. Mod Name: xxx
2. Issue No: xxx
3. UT Status: xxx
4. Dev ID: xxx
5. Loc: xxx
The proposed message does not contain the label: $label" >&2
EOF
exit 1
fi
done
It fails with below error.
28: /mtp-test/script.sh: Syntax error: end of file unexpected (expecting "fi"))
Why does this error occur?
I tried by removing the space/tab before "EOF" as shown below and it worked. I am not sure why space creates an issue.
#!/bin/sh
i=1
label='Mod_Name'
for label in 'Mod_Name' 'Issue No' 'UT Status' 'Dev ID' 'Loc'; do
if ! grep -q "^ $((i++)). $label:" $1; then
cat <<- EOF
Proposed message does not satisfy this repository's exacting standards
It must match the template:
1. Mod_Name: xxx
2. Issue No: xxx
3. UT Status: xxx
4. Dev ID: xxx
5. Loc: xxx
The proposed message does not contain the label: $label" >&2
EOF
exit 1
fi
done

Need to Run Bash commands in groovy Jenkins script

While running this Bash command in an sh """ block I am getting an error in the below Groovy Jenkins code.
I am getting this error:
/home/jenkins/workspace/_api-build_features_SSSVCS-12870#tmp/durable-be642e71/script.sh: line 1: syntax error: unterminated quoted string
for the below 2 lines of Groovy code:
aa = sh(script: "aa=\"\$(helm2 version --short --client|awk '{print substr(\$2,1,2)}'\"; echo \$aa", returnStdout: true).trim()
I am using the variable aa in below if then else loop, Please suggest me.
sh """
if [ aa == v2 ]; then
helm package --save=false ${extraArgs} ${PROJ}
else
helm package ${PROJ}
fi
sh """
In the first line, you miss a closing the bracket ')'. In the second block, consider removing the second sh, otherwise will be part of the whole string between the two """.

Variable assignment in remote server using shell command through Ruby script is not working

I have to run shell command through ruby script in multiple server where as the ruby script will be doing SSH into server and then running that. I am able to run the script till variable assignment into remote machine and then gives me wrong results because the variable assignment at line 15 is not working. Below is the code:
1:require 'open3'
2:require 'net/ssh'
3:require 'fileutils'
4:HOME_PATH = "/road/street/home/"
5:HOME_TAR_FILE = "#{HOME_PATH}/dinner.tar.gz"
6:HOME_REPO = "/road/xyz/abc/dinner.tar.gz"
7:HOME_SOFT = "#{HOME_PATH}home-latest"
8:def home_build_processing(server,user)
9: Net::SSH.start(server, user) do |ssh|
10: ssh.exec!("scp server123:#{HOME_REPO} #{HOME_PATH}")
11: puts "************** Download Completed ****************"
12: ssh.exec!("tar -C #{HOME_PATH} -xvzf #{HOME_TAR_FILE}")
13: ssh.exec!("rm -rf #{HOME_TAR_FILE}")
14: ssh.exec!("cd #{HOME_PATH}; home_latest=$(ls -td -- */ | head -n 1 | cut -d'/' -f1)")
15: ssh.exec!("cd #{HOME_PATH}; home_version=$(echo $home_latest'_'$(date +%Y-%m-%d))")
16: ssh.exec!("cd #{HOME_PATH}; mv $home_latest $home_version")
17: puts "************** Processing Symlink**********************"
18: ssh.exec!("cd #{HOME_PATH}; ln -sfnv $home_version #{HOME_SOFT}")
19: end
20: end
home_build_processing(server1,user1)
home_build_processing(server2,user2)
Error: line 15 home_latest is not having any value
because every exec is a session. The previous variable is already gone.
You can send the command as a chain using &&
"cd #{HOME_PATH}; home_latest=$(ls -td -- */ | head -n 1 | cut -d'/' -f1) && home_version=$(echo $home_latest'...
reference: net-ssh
From net-ssh source code:
exec! same as exec, except this will block until the command finishes. Also,
if no block is given, this will return all output (stdout and stderr)
as a single string.
matches = ssh.exec!("grep something /some/files")
the returned string has an exitstatus method to query it's exit satus
Try something like this
def home_build_processing(server, user)
Net::SSH.start(server, user) do |ssh|
ssh.exec!("scp server123:#{HOME_REPO} #{HOME_PATH}")
puts "************** Download Completed ****************"
ssh.exec!("tar -C #{HOME_PATH} -xvzf #{HOME_TAR_FILE}")
ssh.exec!("rm -rf #{HOME_TAR_FILE}")
home_latest = ssh.exec!("cd #{HOME_PATH}; echo $(ls -td -- */ | head -n 1 | cut -d'/' -f1)")
home_version = ssh.exec!("cd #{HOME_PATH}; echo #{home_latest}'_'$(date +%Y-%m-%d)")
ssh.exec!("cd #{HOME_PATH}; mv #{home_latest} #{home_version}")
puts "************** Processing Symlink**********************"
ssh.exec!("cd #{HOME_PATH}; ln -sfnv #{home_version} #{HOME_SOFT}")
end
end

Executing shell command in groovy throws 'unexpected char' error

I am trying to execute a shell command n groovy
def shellString = "s/\[\|]\|\s\|'\|(\|)//g"
def temp2 = "echo response| sed -e ${shellString}".execute()
It throws compilation error:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 33: unexpected char: '\' # line 33, column 24.
def shellString = "s/\[\|]\|\s\|'\|(\|)//g"
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:150)
at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:120)
at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:132)
at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:350)
at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:139)
at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:110)
at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:234)
at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:168)
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:943)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:605)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:131)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:125)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:560)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:521)
at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:330)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:429)
shellString isn't a slashed string, so not sure why a \ would create a problem. Any help is appreciated.
You need to escape slash to avoid compilation errors:
def shellString = "s/\\[\\|]\\|\\s\\|'\\|(\\|)//g"
def temp2 = "echo response| sed -e ${shellString}".execute()
println temp2.text
Output:
response| sed -e s/\[\|]\|\s\|'\|(\|)//g
This will fail on many levels. The biggest problem you will face is the fact, that execute is really just executing a process (not a shell command). So first of all you can not use | at all. Next quoting arguments will not work, because execute will just split at whitespace. So if you want to use "shellisms" use the equivalent of sh -c "..." instead and use execute on a string array. E.g.
["sh", "-c", "..."].execute()
Then you can put your ... shell code in there with all the redirections, quotings, env-vars etc. with the proper Groovy quoting applied as mentioned in the other answer.
And to circumvent all of that: why even bother with sed here? Just use replaceAll on the resulting string on the groovy side of things.

Error defining variable in bash

I am writing simple housekeeping script. this script contains following line of codes.This is a sample code i have extracted from the actual code since it is a big file.
#!/bin/bash
ARCHIVE_PATH=/product/file
FunctionA(){
ARCHIVE_USER=user1 # archive storage user name (default)
ARCHIVE_GROUP=group1 # archive storage user group (default)
functionB
}
functionB() {
_name_Project="PROJECT1"
_path_Componet1=/product/company/Componet1/Logs/
_path_Component2=/product/company/Componet2/Logs/
##Component1##
archive "$(_name_Project)" "$(_path_Componet1)" "filename1" "file.log"
}
archive(){
_name= $1
_path=$2
_filename=$3
_ignore_filename=$4
_today=`date + '%Y-%m-%d'`
_archive=${ARCHIVE_PATH}/${_name}_$(hostname)_$(_today).tar
if [ -d $_path];then
echo "it is a directory"
fi
}
FunctionA
When i run the above script , i get the following error
#localhost.localdomain[] $ sh testScript.sh
testScript.sh: line 69: _name_Component1: command not found
testScript.sh: line 69: _path_Component2: command not found
date: extra operand `%Y-%m-%d'
Try `date --help' for more information.
testScript.sh: line 86: _today: command not found
it is a directory
Could someone explain me what am i doing wrong here.
I see the line: _today=date + '%Y-%m-%d'
One error I spotted was resolved by removing the space between the + and the ' like so:
_today=date +'%Y-%m-%d'
I don't see where the _name_Component1 and _name_Component2 variables are declared so can't help there :)
Your variable expansions are incorrect -- you're using $() which is for executing a subshell substitution. You want ${}, i.e.:
archive "${_name_Project}" "${_path_Componet1}" "filename1" "file.log"
As for the date error, no space after the +.
a few things... you are using $(variable) when it should be ${variable}
on the date command, make sure there is no space between the + and the format
and you have name= $1, you don't want that space there

Resources