Jenkins error :54: expecting anything but ''\n''; got it anyway - shell

I am using below apache groovy script in jenkins pipeline to deploy my artifact(dev.ear) to server. I have embedded shell script in groovy to securely copy dev.ear from jenkins slave to target server(unix server).
node('linux') {
stage('Checkout/Download/Deploy') {
timeout(time: 30, unit: 'MINUTES') {
def ziptmp = '.ziptmp'
output = sh returnStdout: true, script:"/bin/rm -rf ${ziptmp}; /bin/mkdir ${ziptmp}; cd ${ziptmp}; /usr/bin/unzip -qq ${tempdir}/${artifactFilename}; ls -ltr; echo *;
if [ -e dev.ear ]
then
scp dev.ear lsfi#${serverName57}:/apps/wls/dev/applications;
echo "COPIED DEV ARTIFACT TO SERVER"
else
echo "DEPLOYMENT PACKAGE DOESNT CONTAIN DEV ARTIFACT"
fi"
echo "RESULT::: ${output}"
}
}
}
I am getting the below error when I trigger Jenkins job
WorkflowScript: 54: expecting anything but ''\n''; got it anyway # line 54, column 171.
ctFilename}; ls -ltr; echo *;
I removed new lines in the shell script and updated code as below :
def ziptmp = '.ziptmp'
output = sh returnStdout: true, script:"/bin/rm -rf ${ziptmp}; /bin/mkdir ${ziptmp}; cd ${ziptmp}; /usr/bin/unzip -qq ${tempdir}/${artifactFilename}; ls -ltr; echo *; if [ -e dev.ear ] then scp dev.ear lsfi#${serverName57}:/apps/wls/dev/applications; fi;"
echo "RESULT::: ${output}"
But I am getting the below error :
line 2: syntax error near unexpected token `fi'
How to resolve this error.

Groovy doesn't like a newline in a GString. According to the Grails cookbook you can make multiline Strings using either '''Your multiline String''' or """Your multiline ${GString}""".
I'm not very sure on bash syntax, but you also seem to be missing a semicolon after if [ -e dev.ear ] according to these docs.
Putting it all together:
output = sh returnStdout: true, script: """/bin/rm -rf ${ziptmp}; /bin/mkdir ${ziptmp}; cd ${ziptmp}; /usr/bin/unzip -qq ${tempdir}/${artifactFilename}; ls -ltr; echo *;
if [ -e dev.ear ];
then
scp dev.ear lsfi#${serverName57}:/apps/wls/dev/applications;
echo "COPIED DEV ARTIFACT TO SERVER"
else
echo "DEPLOYMENT PACKAGE DOESNT CONTAIN DEV ARTIFACT"
fi"
echo "RESULT::: ${output}"""

Related

How to convert systemv startup scripts to systemd services?

Advice on converting SysVinit file to Systemd services will be helpful.
Currently, I am using a systemv init script which will be executed after every boot on my STM32MP1 based Avenger96 board. Now I have to switch to Systemd from SysVinit. But I am not sure how to convert the init file to relevant systemd files. I am using Yocto with Ubuntu20.04 as build system. If someone help me to get started would be really great. Below is the init script and image recipe which establishes symlink to the init script.
custom-script.sh which is installed in etc/init.d/ directory of the rootfs.
#!/bin/sh
DAEMON="swupdate"
PIDFILE="/var/run/$DAEMON.pid"
PART_STATUS=$(sgdisk -A 4:get:2 /dev/mmcblk0)
if test "${PART_STATUS}" = "4:2:1" ; then
ROOTFS=rootfs-2
else
ROOTFS=rootfs-1
fi
if test -f /update-ok ; then
SURICATTA_ARGS="-c 2"
rm -f /update-ok
fi
start() {
printf 'Starting %s: ' "$DAEMON"
# shellcheck disable=SC2086 # we need the word splitting
start-stop-daemon -b -q -m -S -p "$PIDFILE" -x "/usr/bin/$DAEMON" \
-- -f /etc/swupdate/swupdate.cfg -L -e rootfs,${ROOTFS} -u "${SURICATTA_ARGS}"
status=$?
if [ "$status" -eq 0 ]; then
echo "OK"
else
echo "FAIL"
fi
return "$status"
}
stop() {
printf 'Stopping %s: ' "$DAEMON"
start-stop-daemon -K -q -p "$PIDFILE"
status=$?
if [ "$status" -eq 0 ]; then
rm -f "$PIDFILE"
echo "OK"
else
echo "FAIL"
fi
return "$status"
}
restart() {
stop
sleep 1
start
}
case "$1" in
start|stop|restart)
"$1";;
reload)
# Restart, since there is no true "reload" feature.
restart;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
Image recipe which creates init.d dir and installs above script and also establishes symlink to rc4.d dir.
custom-image.bb
.
.
inherit update-rc.d
SRC_URI = "file://custom-script.sh \
"
S = "${WORKDIR}"
INITSCRIPT_PACKAGES = "${PN}"
INITSCRIPT_NAME = "custom-script.sh"
INITSCRIPT_PARAMS = "start 99 2 3 4 5 . "
do_install_append() {
install -d ${D}${sysconfdir}/rc4.d
install -d 644 ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/custom-script.sh ${D}${sysconfdir}/init.d
ln -sf ../init.d/custom-script.sh ${D}${sysconfdir}/rc4.d/S99custom-script.sh
ln -sf ../init.d/custom-script.sh ${D}${sysconfdir}/rc4.d/K99custom-script.sh
}
FILES_${PN} += "${sysconfdir}/init.d"
Now I am trying to do the same functionality of custom-script.sh with systemd. Is it possible to make use of systemd-sysv-generator in this case?
Also, will the dir init.d completely removed once we switch to "systemd"? What will happen to other files which are present in etc/init.d?
Can anyone please help me get started?
Your help will be much appreciated.
Thanks in advance.
P.S: Please let me know if any info is missing here.
/etc/init.d will not get deleted by using systemd
Have you checked /etc/systemd and /usr/lib/systemd on your Ubuntu machine for examples of systemd scripts. Along the manual pages of systemd, you should have enough examples to convert your sysv init script to systemd.

If statement doesn't execute argument

GNU nano 2.7.4 File: /home/pi/initDisplay/initDisplay.sh
#!/usr/bin/env bash
#HDMI connection?
rm -f hdmi.name
tvservice -n 2>hdmi.name
HDMI_NAME=`cat hdmi.name`
echo $HDMI_NAME
if [ "$HDMI_NAME" == "[E] No device present" ]; then
LCD_ON=`cat /boot/config.txt | grep "#CONFIGURAZIONEHDMI"`
echo $LCD_ON
if [ "$LCD_ON" == "#CONFIGURAZIONEHDMI" ]; then
echo "reboot con la configurazione LCD"
sudo rm -f /boot/config.txt
sudo cp /boot/config_lcd.txt /boot/config.txt
sleep 2
sudo reboot -n
fi
else
HDMI_ON=`cat /boot/config.txt | grep "#CONFIGURAZIONELCD"`
echo $HDMI_ON
if [ $HDMI_ON == "#CONFIGURAZIONELCD" ]; then
echo "reboot con la configurazione HDMI"
sudo rm -f /boot/config.txt
sudo cp /boot/config_hdmi.txt /boot/config.txt
sleep 2
sudo reboot -n
fi
fi
Doesn't start the arg of if statement with $LCD_ON. When I try to execute it, it doesn't return what I expect. Now it returns:
[E] no device detected
#CONFIGURAZIONEHDMI
but it doesn't start to replace file and reboot.
P.S.: The user and the file have privileges to do it
And I already set chmod 777 the file
There might be more on the line that matches, such as extra whitespace, so the equality test doesn't match exactly.
If you want to test whether a matching line exists in a file, you can just test the exit status of grep, rather than storing the output in a variable.
if grep -q "#CONFIGURAZIONEHDMI" /boot/config.txt; then
echo "reboot con la configurazione LCD"
sudo rm -f /boot/config.txt
sudo cp /boot/config_lcd.txt /boot/config.txt
sleep 2
sudo reboot -n
fi
The -q option tells grep not to print the matching line, it just sets its exit status.

Bash sub script redirects input to /dev/null mistakenly

I'm working on a script to automate the creation of a .gitconfig file.
This is my main script that calls a function which in turn execute another file.
dotfile.sh
COMMAND_NAME=$1
shift
ARG_NAME=$#
set +a
fail() {
echo "";
printf "\r[${RED}FAIL${RESET}] $1\n";
echo "";
exit 1;
}
set -a
sub_setup() {
info "This may overwrite existing files in your computer. Are you sure? (y/n)";
read -p "" -n 1;
echo "";
if [[ $REPLY =~ ^[Yy]$ ]]; then
for ARG in $ARG_NAME; do
local SCRIPT="~/dotfiles/setup/${ARG}.sh";
[ -f "$SCRIPT" ] && echo "Applying '$ARG'" && . "$SCRIPT" || fail "Unable to find script '$ARG'";
done;
fi;
}
case $COMMAND_NAME in
"" | "-h" | "--help")
sub_help;
;;
*)
CMD=${COMMAND_NAME/*-/}
sub_${CMD} $ARG_NAME 2> /dev/null;
if [ $? = 127 ]; then
fail "'$CMD' is not a known command or has errors.";
fi;
;;
esac;
git.sh
git_config() {
if [ ! -f "~/dotfiles/git/gitconfig_template" ]; then
fail "No gitconfig_template file found in ~/dotfiles/git/";
elif [ -f "~/dotfiles/.gitconfig" ]; then
fail ".gitconfig already exists. Delete the file and retry.";
else
echo "Setting up .gitconfig";
GIT_CREDENTIAL="cache"
[ "$(uname -s)" == "Darwin" ] && GIT_CREDENTIAL="osxkeychain";
user " - What is your GitHub author name?";
read -e GIT_AUTHORNAME;
user " - What is your GitHub author email?";
read -e GIT_AUTHOREMAIL;
user " - What is your GitHub username?";
read -e GIT_USERNAME;
if sed -e "s/AUTHORNAME/$GIT_AUTHORNAME/g" \
-e "s/AUTHOREMAIL/$GIT_AUTHOREMAIL/g" \
-e "s/USERNAME/$GIT_USERNAME/g" \
-e "s/GIT_CREDENTIAL_HELPER/$GIT_CREDENTIAL/g" \
"~/dotfiles/git/gitconfig_template" > "~/dotfiles/.gitconfig"; then
success ".gitconfig has been setup";
else
fail ".gitconfig has not been setup";
fi;
fi;
}
git_config
In the console
$ ./dotfile.sh --setup git
[ ?? ] This may overwrite existing files in your computer. Are you sure? (y/n)
y
Applying 'git'
Setting up .gitconfig
[ .. ] - What is your GitHub author name?
Then I cannot see what I'm typing...
At the bottom of dotfile.sh, I redirect any error that occurs during my function call to /dev/null. But I should normally see what I'm typing. If I remove 2> /dev/null from this line sub_${CMD} $ARG_NAME 2> /dev/null;, it works!! But I don't understand why.
I need this line to prevent my script to echo an error in case my command doesn't exists. I only want my own message.
e.g.
$ ./dotfile --blahblah
./dotfiles: line 153: sub_blahblah: command not found
[FAIL] 'blahblah' is not a known command or has errors
I really don't understand why the input in my sub script is redirected to /dev/null as I mentioned only stderr to be redirected to /dev/null.
Thanks
Do you need the -e option in your read statements?
I did a quick test in an interactive shell. The following command does not echo characters :
read -e TEST 2>/dev/null
The following does echo the characters
read TEST 2>/dev/null

Adding to /etc/profile.d from bash script fails

I have the following problem. I need to create system-wide JDK_HOME and JAVA_HOME variables. First I want to create /etc/profile.d/java.sh and add
JDK_HOME to it. Then I want to append JAVA_HOME to this file. So far I have this code.
#!/bin/bash
create_env_var()
{
local varname="$1"
local varvalue="$2"
local filename="/etc/profile.d/$3"
if [ -e "$filename" ]; then
echo "**ERROR: file $filename already exists"
else
sh -c 'echo "$varname=$varvalue" > $filename'
chmod +x "$filename"
fi
}
append_env_var()
{
local varname="$1"
local varvalue="$2"
local filename="/etc/profile.d/$3"
if [ ! -e "$filename" ]; then
echo "**ERROR: file $filename not found"
else
sh -c 'echo "$varname=$varvalue" >> $filename'
chmod +x "$filename"
fi
}
create_env_var "JDK_HOME" "/usr/lib/jvm/java-7-openjdk-i386" "java.sh"
append_env_var "JAVA_HOME" "/usr/lib/jvm/java-7-openjdk-i386" "java.sh"
exit "$?"
However these lines don't work and I see the following errors:
sh: 1: cannot create : Directory nonexistent
chmod: cannot access ‘/etc/profile.d/java.sh’: No such file or directory
Would you please show me where everything goes wrong?
While you can remove the single quotes, there's no reason to create a subprocess and use sh -c.
change sh -c 'echo "$varname=$varvalue" > $filename'
to echo "$varname=$varvalue" > $filename
and sh -c 'echo "$varname=$varvalue" >> $filename'
to echo "$varname=$varvalue" >> $filename

Using shell scripts to remove clearcase view if it exists using one liner if

I want to test if a clearcase view exists and execute the remove command only if it exists. I am trying to do it from a shell script in a Linux 6.x environment. I tried to format my conditions both as one-liner as well as full "if" statement, but don't seem to be able to get it to work. What do I need to do to get both - one-liner and full if syntax - approaches working?
Here is the code, in its latest state
#!/bin/ksh
#
STREAMNAME=app_stream_int
PVOB=domain_pvob
VOB=domain_app
viewdir=/opt/local/software/rational/viewstorage
shareddir=/opt/shared/test
storagedir=${shareddir}/viewstorage
projectdir=${shareddir}/projects
ctdir=/opt/rational/clearcase/bin
viewname=$viewdir/test_$STREAMNAME.vws
viewtag=test_$STREAMNAME
echo "STREAMNAME $STREAMNAME - PVOB $PVOB - VOB $VOB"
echo "Removing View if it exists ... \n"
# [ $(${ctdir}/cleartool lsview ${viewname}) ] && { ${ctdir}/cleartool rmview ${viewname}; echo "view removed" }
# [ ${ctdir}/cleartool lsview -long ${viewtag} ] && { ${ctdir}/cleartool rmview ${viewname}; echo "view removed" }
# ${ctdir}/cleartool lsview -long ${viewtag} | grep "Tag" && { ${ctdir}/cleartool rmview ${viewname}; echo "view removed" }
if [ ${ctdir}/cleartool lsview -long ${viewtag} | grep 'Tag' == "0" ]
then
echo "view found"
${ctdir}/cleartool rmview ${viewname}
fi
I would prefer a one-liner type of solution, but 'if' statement will also work.
Provided the command follows the UNIX-convention of exit codes, the general one-liner looks like:
command && { success1; success2; } || { failure1; failure2; }
The list following && specifies what should run when command succeeds (exits with 0), while the list following || specifies what should run when the command fails. In the list, note that all the commands end in a semi-colon, including the last one.
For your specific case, this looks like it'll work:
"${ctdir}"/cleartool lsview "${viewname}" && { "${ctdir}"/cleartool rmview "${viewname}" && echo "view removed" || echo "cannot remove view"; }
Here is an example of this pattern in action, using standard commands:
$ ls foo && { rm -f foo && echo 'removed' || echo 'not removed'; }
ls: cannot access foo: No such file or directory
$ touch foo
$ ls foo && { rm -f foo && echo 'removed' || echo 'not removed'; }
foo
removed
$ sudo touch /foo
$ sudo chmod 600 /foo
$ ls /foo && { rm -f /foo && echo 'removed' || echo 'not removed'; }
/foo
rm: cannot remove ‘/foo’: Permission denied
not removed

Resources