Syntax Error: Multiline bash command in dockerfile RUN statement - linux

I have this Dockerfile, to which I am echoing the following line:
echo $"RUN cat file | while read pkg \
do\
sudo apt-get install -qy $pkg \
done" >> Dockerfile
Now, when docker executes this line, I get the following error:
/bin/sh: -c: line 1: syntax error: unexpected end of file
The command '/bin/sh -c cat autobuild/buildenv_packages | while read pkg do sudo apt-get install -qy done' returned a non-zero code: 1
I know there is something small and syntactical I am missing, but I am unable to figure it out. Notice that the $pkg variable in the apt-get install statement isn't in the error.
Any assistance would be appreciated!

The backslashes in your code only prevent the string from containing literal newlines; they are not written to the Dockerfile. Without a newline (or a semicolon) before do, the while condition never ends; you just have a giant list of arguments for the command read.
echo 'RUN while read pkg; do sudo apt-get install -qy "$pkg"; done < file' >> Dockerfile

Related

SSH Bash script issues with if statement

I'm trying to learn how to write Bash scripts. I have this script to update my servers through ssh. I'm trying to add a check and a conditional to determine if the OS uses Yum or Apt then it will run the appropriate update commands. The if else statement seems to be wrong but I'm not sure how to correct this.
Here is the script:
#!/bin/bash
USERNAME="root"
HOSTS="host1 host2 host3"
apt_run="apt update && apt -y upgrade"
yum_run="yum check-update && yum -y update"
for HOSTNAME in ${HOSTS} ; do
ssh -l ${USERNAME} ${HOSTNAME}
find_os=$( command -v yum || command -v apt-get ) || echo "Neither
yum nor apt-get found"
if [[ $find_os='yum' ]]
then
"${yum_run}"
else
"${apt_run}"
fi
done
Here is my script for my virtual machines.
#!/bin/bash
hosts=(
leap151 kali ubuntu omv
)
for hostname in "${hosts[#]}"; do
ssh -t root#"$hostname" << 'EOF'
if type -P zypper >/dev/null; then
command zypper ref && command zypper up
elif type -P apt-get >/dev/null; then
command apt-get update && command apt-get upgrade
else
echo 'Neither zypper nor apt found!' >&2
exit 127
fi
EOF
done
Use an array for the host. Since you're using bash the builtin type is fine just for searching the executable within your PATH. See help type for more info. Use the -t option in ssh also use a heredoc just what I have/did. The exit 127 is what the shell would exit if there are no executable see man 1p exit.

ffmpeg getting syntax error when run inside shell script only.. Why? [duplicate]

This question already has answers here:
Bash: Syntax error: redirection unexpected
(9 answers)
Closed 8 years ago.
I have the following script:
#!/bin/sh
# Use the PhiPack software on our two aligned sets of sequences...
mkdir FcFeABC
cd FcFeABC
../bin/PhiPack/Phi -f ../../Data/Real_Sequences_and_Networks/FcFeABC_alignment.fas -o -v -w 10 -g
cd -
mkdir FcL10
cd FcL10
../bin/PhiPack/Phi -f ../../Data/Real_Sequences_and_Networks/FcL10_alignment.fas -o -v -w 10 -g
cd -
# Use the PhiPack software on the simulated Datasets...
cd ../Data/Simulated_Sequences_and_Networks/Constant_Sex/Theta\ =\ 0.066/Theta\ =\ 0.066/Medium/CutSequences/;
rmus=($(ls -d *.fas))
cd -
absfiles=(../Data/Simulated_Sequences_and_Networks/Constant_Sex/Theta\ =\ 0.066/Theta\ =\ 0.066/Medium/CutSequences/*.fas)
if [ ${#rmus[#]} = ${#absfiles[#]} ]
then
mkdir ${rmus[#]}
for ((i=0; i<${#absfiles[#]}; i++));
do
cd ${rmus[$i]}
.../bin/PhiPack/Phi -f ${absfiles[$i]} -o -v -w 10 -g
cd -
done
else
echo "Error, Number of files created and files to be read differs"
fi
Which hit's an error at line 16:
./runPhiTests.sh: 16: ./runPhiTests.sh: Syntax error: "(" unexpected
Which is this line:
rmus=($(ls -d *.fas))
I don't understand why the '(' is unexpected - it's a simple assignment of the results of ls to an array.
Thanks,
Ben W.
You aren't running it with bash. You are running with /bin/sh from your shebang line #!/bin/sh.
Either run with bash explicitly bash runPhiTests.sh or fix your shebang line #!/bin/bash.
Try to use #!/bin/bash instead of sh.

Multiline bash command in Jenkins pipeline

I have the following sh command in my Jenkinsfile which does not work because it tries to execute the last "DATA" as a command.
If I move last "DATA" to the beginning of the line it works but is not as beautiful as I want.
Is there a way to the indention in this case?
sh """
sshpass -p 'password' ssh -o StrictHostKeyChecking=no appsadm#$backup_registry <<DATA
sudo /etc/init.d/docker stop || true
sudo yum remove -y docker-engine.x86_64
sudo rm -fr /var/lib/docker /var/log/docker
sudo rpm -iUvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm || true
sudo yum update -y
sudo yum -y install docker-io
sudo sed -i 's#other_args=.*#other_args="--insecure-registry $official_registry:5000"#g' /etc/sysconfig/docker
sudo /etc/init.d/docker start
DATA
"""
I know this is an old question, but I had ran into this at some point, and eventually ended up using stripIndent()
steps {
echo 'Deploying....'
sh """
ssh somewhere <<EOF
cd somewhere
do some more stuff
EOF
""".stripIndent()
}
That way you can still keep your indentations and formatting
because <<DATA specifies the end of here-doc <<-DATA suppress leading tabs but not spaces
cat <<-DATA
hello
<tab>DATA
another option is to add spaces in marker
cat << " DATA"
hello
DATA
Edit: We don't need to use EOF, simply put the semicolon at the end of statement on multiline shell script as shown below
sh """ if [ -d /opt/tomcat/apache-tomcat-8.5.38/webapps/ROOT ] ;
then ;
ssh $USERNAME#$DEV_HOSTNAME 'sudo rm -rf /opt/tomcat/apache-tomcat-8.5.38/webapps/ROOT' ;
echo 'ROOT directory deleted successfully' ;
fi ;
"""

./autogen.sh gives : invalid option

I want to add libcrafter file in cpp file which is provided from https://github.com/pellegre/libcrafter In that they provide steps
cd libcrafter/libcrafter
$ ./autogen.sh
$ make
$ sudo make install
$ sudo ldconfig
But when I run command it gives invalid option
I have already installed
sudo apt-get install autoconf libtool
sudo apt-get install libpcap0.8 libpcap0.8-dev
#!/bin/sh -e
test -n "$srcdir" || srcdir=`dirname "$0"`
test -n "$srcdir" || srcdir=.
autoreconf --force --install --verbose "$srcdir"
test -n "$NOCONFIGURE" || "$srcdir/configure" "$#"
Error:
libcrafter$ sudo ./autogen.sh
[sudo] password for altaf: : invalid option

Bash string manipulation works differently in shell than .sh file?

I have a script to get and setup the latest NodeJS on my .deb system:
echo "Downloading, building and installing latest NodeJS"
sudo apt-get install python g++ make checkinstall
mkdir /tmp/node_build && cd $_
curl -O "http://nodejs.org/dist/node-latest.tar.gz"
tar xf node-latest.tar.gz && cd node-v*
NODE_VERSION="${PWD#*v}"
#NODE_VERSION=python -c "print '$PWD'.split('-')[-1][1:]"
echo "Installing NodeJS" $NODE_VERSION
./configure
sudo checkinstall -y --install=no --pkgversion NODE_VERSION
sudo dpkg -i node_$NODE_VERSION
Unfortunately it doesn't work; as the echo line outputs:
Installing NodeJS i8/dir-where-runnning-script-from/node-v0.10.24
It does work from the shell though:
$ cd /tmp/node_build/node-v0.10.24 && echo "${PWD#*v}"
0.10.24
Is there another "v" in the path, like right before the "i8/"? #*v will remove through the first "v" in the variable; I'm pretty sure you want ##*v which'll remove through the last "v" in the variable. (Technically, # removes the shortest matching prefix, and ## removes the longest match). Thus:
NODE_VERSION="${PWD##*v}"
Should work.
Try this
sudo checkinstall -y --install=no --pkgversion "${NODE_VERSION##*v}"

Resources