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 ]; 
   echo "Removing previous backup"
   docker rm -f -v \$(docker ps -a -q --filter name=backup)
   sudo rm -rf ${TRAVIS_REPO_SLUG#*/}-${TRAVIS_BRANCH}-*-backup

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

  • 9
    Quote your variables. Quote your variables. Repeat after me: quote your variables. Oct 9, 2018 at 10:46
  • 4
    Possible duplicate of $VAR vs ${VAR} and to quote or not to quote Oct 9, 2018 at 10:49
  • 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 Oct 9, 2018 at 11:14
  • 1
    Call the script with bash -x to see what happens Oct 9, 2018 at 11:18
  • 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 9, 2018 at 11:21

1 Answer 1

[ -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:

# 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
if [ "$any" = 1 ]; then
    echo "some directories matching $a-$b-*-backup were found"

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:

shopt -s nullglob
set -- $a-$b-*-backup/
if [ "$#" != 0 ]; then
    echo "$# directories matching $a-$b-*-backup were found"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .