LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 02-12-2021, 01:46 AM   #1
sysmicuser
Member
 
Registered: Mar 2010
Posts: 458

Rep: Reputation: 0
Unhappy bash if loop produces error


Hello,

The snippet of my shell script is as follows:

Code:
mkdir -p /tmp/aa1

if [ "${consider_kinds}" = "all" ] || [ "${consider_kinds}" = "serviceaccounts" ]
then
        echo "Uploading source serviceaccounts"
        cd ${HOME}/sync-cluster/${consider_namespace}/serviceaccounts
        if [ ! -f *.yaml || ! -f *.yml ]
        then
                echo "No yaml manifest file found"
        else
                list_of_files=$(ls -lrt|awk '{print $9}')
                curl --user "${deploy_user}:${deploy_user_password}" -XPUT "https://testcomany.com.au/testrepovirtual/Clustersync/" -H "Content-Type: application/json" -T ${list_of_files}
        fi
fi

if [ "${consider_kinds}" = "all" ] || [ "${consider_kinds}" = "secrets" ]
then
        echo "Uploading source secrets"
        cd ${HOME}/sync-cluster/${consider_namespace}/secrets
        if [ ! -f *.yaml || ! -f *.yml ]
        then
                echo "No yaml manifest file found"
        else
                list_of_files=$(ls -lrt|awk '{print $9}')
                curl --user "${deploy_user}:${deploy_user_password}" -XPUT "https://testcomany.com.au/testrepovirtual/Clustersync/" -H "Content-Type: application/json" -T ${list_of_files}
        fi
fi

if [ "${consider_kinds}" = "all" ] || [ "${consider_kinds}" = "configmaps" ]
then
        echo "Uploading source configmaps"
        cd ${HOME}/sync-cluster/${consider_namespace}/configmaps
        if [ ! -f *.yaml || ! -f *.yml ]
        then
                echo "No yaml manifest file found"
        else
                list_of_files=$(ls -lrt|awk '{print $9}')
                curl --user "${deploy_user}:${deploy_user_password}" -XPUT "https://testcomany.com.au/testrepovirtual/Clustersync/" -H "Content-Type: application/json" -T ${list_of_files}
        fi
fi

if [ "${consider_kinds}" = "all" ] || [ "${consider_kinds}" = "deployments & services" ]
then
        echo "Uploading source deployments"
        cd ${HOME}/sync-cluster/${consider_namespace}/deployments
        if [ ! -f *.yaml || ! -f *.yml ]
        then
                echo "No yaml manifest file found"
        else
                list_of_files=$(ls -lrt|awk '{print $9}')
                curl --user "${deploy_user}:${deploy_user_password}" -XPUT "https://testcomany.com.au/testrepovirtual/Clustersync/" -H "Content-Type: application/json" -T ${list_of_files}
        fi
        cd ${HOME}/sync-cluster/${consider_namespace}/services
        if [ ! -f *.yaml || ! -f *.yml ]
        then
                echo "No yaml manifest file found"
        else
                list_of_files=$(ls -lrt|awk '{print $9}')
                 curl --user "${deploy_user}:${deploy_user_password}" -XPUT "https://testcomany.com.au/testrepovirtual/Clustersync/" -H "Content-Type: application/json" -T ${list_of_files}
        fi
fi
However, I am getting error like below

Code:
./jenkins-part-compose-structure.sh: line 63: [: missing `]'
+ -f '*.yml' ']'
./jenkins-part-compose-structure.sh: line 63: -f: command not found
What I basically want to do is, if there are YAML or YML file(s) are present then get their names so they can be uploaded to the artifactory.

But if the file is not present I don't want the script to fail, it could be legit not to have any particular resource.

What mistake am I making here?
 
Old 02-12-2021, 04:18 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,041

Rep: Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348
a missing [
Code:
if [ ! -f *.yaml || ! [ -f *.yml ]
I would suggest you to use shellcheck to analyze your script.
 
Old 02-12-2021, 10:10 AM   #3
berndbausch
LQ Addict
 
Registered: Nov 2013
Location: Tokyo
Distribution: Mostly Ubuntu and Centos
Posts: 6,316

Rep: Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002Reputation: 2002
Also, please don't call the if construct a "loop". Nothing loops here. if runs code conditionally.
 
Old 02-12-2021, 02:31 PM   #4
computersavvy
Senior Member
 
Registered: Aug 2016
Posts: 3,345

Rep: Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484
shellcheck gives lots of errors and suggestions on that code snippet.
 
Old 02-12-2021, 05:22 PM   #5
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219
Must be either the deprecated
Code:
if [ ! -f *.yaml -o ! -f *.yml ]
or
Code:
if [ ! -f *.yaml ] || [ ! -f *.yml ]
Still bad, because one token is expected where the glob matches can generate zero or multiple tokens.

A nice fix is a function:
Code:
file_exists() {
  for _i
  do [ -f "$_i" ] && return
  done
  return 1
}
Now it is straight forward
Code:
if ! file_exists *.yaml || ! file_exists *.yml
Last but not least, check the logic!
Doesn't the following make more sense?
Code:
if ! file_exists *.yaml && ! file_exists *.yml
Code:
if ! { file_exists *.yaml || file_exists *.yml; }
Code:
if ! file_exists *.yaml *.yml

Last edited by MadeInGermany; 02-12-2021 at 05:30 PM.
 
Old 02-12-2021, 07:23 PM   #6
computersavvy
Senior Member
 
Registered: Aug 2016
Posts: 3,345

Rep: Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484
shellcheck said that the test cannot use -f with a glob and suggested using a for loop instead. Simple enough fix.

maybe a -e would work.
Code:
if ! [ -e *.yaml ] || ! [ -e *.yml ]
should work, but I did not try it

The for loop could be
Code:
yamlExists=1
for i in *.yaml ; do yamlExists=0 ; done
if [ "yamlExists" == "1" ]; then
   .....
fi
and a similar loop and test for the *.yml files

Last edited by computersavvy; 02-12-2021 at 07:44 PM.
 
Old 02-13-2021, 07:36 AM   #7
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219
The -e does not improve anything.
A for loop is the straight fix (and preferrable over other solutions like "ls -A" ).
And hiding the loop in a universal function is most elegant
 
Old 02-13-2021, 08:49 AM   #8
JJJCR
Senior Member
 
Registered: Apr 2010
Posts: 2,167

Rep: Reputation: 449Reputation: 449Reputation: 449Reputation: 449Reputation: 449
My 2 cents:

Quote:
if ls {*.yaml,*.yml} 1> /dev/null 2>&1; then

echo "files do exist"

else

echo "files do not exist"

fi

Last edited by JJJCR; 02-13-2021 at 08:49 AM. Reason: edit
 
Old 02-13-2021, 09:33 AM   #9
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
@JJJCR. And what if there are *.yaml files, but no *.yml files, or vice versa?
 
Old 02-13-2021, 10:22 AM   #10
JJJCR
Senior Member
 
Registered: Apr 2010
Posts: 2,167

Rep: Reputation: 449Reputation: 449Reputation: 449Reputation: 449Reputation: 449
Lightbulb

Quote:
Originally Posted by shruggy View Post
@JJJCR. And what if there are *.yaml files, but no *.yml files, or vice versa?
Yes, that statement is "and" and will return none if one is missing.

edit to this one:

Quote:
GNU nano 4.3 testx.sh

#!/bin/sh



if ls | egrep '\.yaml$|\.yml$' 1> /dev/null 2>&1; then

echo "files do exist"

else

echo "files do not exist"

fi


 
Old 02-13-2021, 10:28 AM   #11
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
Code:
if grep -qs . *.yaml *.yml
then echo 'files do exist'
else echo 'files do not exist'
fi
 
Old 02-13-2021, 10:44 AM   #12
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,832

Rep: Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219Reputation: 1219
Cannot say that I like that opening of the files.
At least improve it to not require a character:
Code:
if grep -qs '^' *.yaml *.yml
 
Old 02-13-2021, 11:09 AM   #13
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 3,678

Rep: Reputation: Disabled
Many grep-like tools (ack, ag, etc.) have the -g option precisely for this, they're not part of the standard Unix toolbox though. I use them all the time on the command line, but not in scripts.
 
1 members found this post helpful.
Old 02-13-2021, 11:56 PM   #14
sysmicuser
Member
 
Registered: Mar 2010
Posts: 458

Original Poster
Rep: Reputation: 0
Amazing people, Many thanks! Shell check helped a lot.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Sed script within bash script produces unexpecte EOF error Kgeil Linux - Newbie 8 05-16-2019 12:41 AM
LXer: FAIL: Windows 10 bulk patch produces INFINITE CRASH LOOP LXer Syndicated Linux News 0 08-12-2015 01:22 AM
how to loop over text file lines within bash script for loop? johnpaulodonnell Linux - Newbie 9 07-28-2015 03:49 PM
loop produces wierd numbers turf Programming 2 08-13-2010 05:20 AM
bash loop within a loop for mysql ops br8kwall Programming 10 04-30-2008 03:50 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 10:56 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration