0

My directory structure is something like below.

.
|- test-master-65875866-backup        
|- test-master-86565875

I tried the following code (also with double brackets)

if [ -d ${TRAVIS_REPO_SLUG#*/}-${TRAVIS_BRANCH}-*-backup ]; 
 then
   echo "Removing previous backup"
   docker rm -f -v \$(docker ps -a -q --filter name=backup)
   sudo rm -rf ${TRAVIS_REPO_SLUG#*/}-${TRAVIS_BRANCH}-*-backup
fi

but I'm still getting the error:

[: binary operator expected

I am wondering this error getting only in travis but not in local.

Note: ${TRAVIS_REPO_SLUG#*/} contains test and ${TRAVIS_BRANCH} contains master here.

I tried all of the following permutations but the error won't go away.

if [ -d "$TRAVIS_REPO_SLUG#*/"-"$TRAVIS_BRANCH"-*-backup ]; then

if [ -d "${TRAVIS_REPO_SLUG#*/}"-"${TRAVIS_BRANCH}"-*-backup ]; then

if [ -d "${TRAVIS_REPO_SLUG#*/}-${TRAVIS_BRANCH}-*-backup" ]; then

However the below code (with !) doesn't provide any error.

if [ ! -d ${TRAVIS_REPO_SLUG#*/}-${TRAVIS_BRANCH}-*-backup ]

Here is my complete code

Fabby
  • 5,384
SkyRar
  • 191
  • 9
    Quote your variables. Quote your variables. Repeat after me: quote your variables. – Chris Davies Oct 09 '18 at 10:46
  • In case that's not clear, instead of printf %s $a you should use printf %s "$a". – Chris Davies Oct 09 '18 at 10:47
  • @roaima Yes I tried quoting variables also. But same error. – SkyRar Oct 09 '18 at 10:48
  • 4
  • I tried to minimize error like this 2> /dev/null but same error – SkyRar Oct 09 '18 at 10:50
  • If you were already quoting variables please amend your question to give an example of how you were quoting them, because it's the obvious mistake in your code. – Chris Davies Oct 09 '18 at 10:53
  • @roaima Yes I edited my question. – SkyRar Oct 09 '18 at 11:00
  • 3
    Do you want to check that all the files that match "${TRAVIS_REPO_SLUG#*/}"-"${TRAVIS_BRANCH}"-*-backup are of type directory? Or that there is at least one that is of type directory? In any case [ -d file ] can take only one file, so you'll probably need a loop or a shell with glob qualifiers – Stéphane Chazelas Oct 09 '18 at 11:14
  • @StéphaneChazelas I have only two dirs those are test-master-65875866-backup and test-master-86565875 . So according to condition there is only one dir which matches the pattern – SkyRar Oct 09 '18 at 11:17
  • 1
    Call the script with bash -x to see what happens – Stéphane Chazelas Oct 09 '18 at 11:18
  • @StéphaneChazelas Actually I am executing the script over ssh and the codes are within EOF block. Can you tell mw where should I append the bash -x ? – SkyRar Oct 09 '18 at 11:20
  • 1
    Please do what Stéphane said or if your script is too long use set -x before and set +x after the offending code and then [edit] your question and provide the output of your script... – Fabby Oct 09 '18 at 11:21
  • I have edited the question with a gist link to complete bash script. Can you tell me where should I append the set -x ? inside EOF block or outside ? – SkyRar Oct 09 '18 at 11:25
  • You're using << EOF instead of << 'EOF' so the variables are expanded by the local shell inside the here-doc. – Stéphane Chazelas Oct 09 '18 at 11:26
  • @StéphaneChazelas That is intentional to substitute travis variables inside the EOF block. But how does it matter ? Before executing EOF block the variables are got substituted if I am not wrong .. – SkyRar Oct 09 '18 at 11:29
  • @StéphaneChazelas However please check the line number #23 https://gist.github.com/dbjpanda/db5581e9cba9a0d1a0629d7a47d05151#file-deploy-sh-L23 . It works perfectly – SkyRar Oct 09 '18 at 11:30
  • 1
    As per @Fabby I appended -x and +x and here is the output https://gist.github.com/dbjpanda/db5581e9cba9a0d1a0629d7a47d05151#gistcomment-2727526 – SkyRar Oct 09 '18 at 11:35
  • BTW thanks guys. I figured out after setting -x that error is due to line number https://gist.github.com/dbjpanda/db5581e9cba9a0d1a0629d7a47d05151#file-deploy-sh-L55 where * evaluates to two directories. And the error is obvious. My bad. – SkyRar Oct 09 '18 at 11:41
  • I was waiting for @StéphaneChazelas to post an answer as he put most work in... Stéphane? À toi ou à moi de jouer? ;-) – Fabby Oct 09 '18 at 11:45
  • 1
    @Fabby, go for it. – Stéphane Chazelas Oct 09 '18 at 11:48
  • @SkyRar Just post your own answer is going to be easier for everyone involved. As you're new here, please post the answer in the box below and do not change your question at this point. Then accept your own answer by clicking the grey check mark next to it! :-) – Fabby Oct 10 '18 at 08:46

1 Answers1

2
[ -d ${TRAVIS_REPO_SLUG#*/}-${TRAVIS_BRANCH}-*-backup ];

The unquoted * here will expand to any matching filenames

$ mkdir test-master-123-backup test-master-456-backup
$ a=test b=master
$ echo $a-$b-*-backup
test-master-123-backup test-master-456-backup

So [ gets more arguments than it expects for -d. It probably gets three in total (-d and to filenames), since that's the case where it expects the middle one to be a binary operator as the error message hints.

The version where the * is quoted shouldn't give the same error, instead it will look for a file with a literal * in the name, which is probably not what you want.

If you want to see if there are any directories matching that pattern, you could do something like this:

any=0
# set IFS to empty if you expect to have directories with whitespace in names
# IFS=''    
for f in $a-$b-*-backup; do
    if [ -d "$f" ]; then
        any=1
    fi
done
if [ "$any" = 1 ]; then
    echo "some directories matching $a-$b-*-backup were found"
fi

Or, in a bit simpler way in Bash. The trailing slash makes the glob only match directories, and nullglob makes the glob turn into an empty list if it doesn't match anything:

IFS=''
shopt -s nullglob
set -- $a-$b-*-backup/
if [ "$#" != 0 ]; then
    echo "$# directories matching $a-$b-*-backup were found"
fi
ilkkachu
  • 138,973