-1

I'm trying to write a function that does this:

$ test-function -u {local-path} {destination}

If the first parameter is -u, then execute a function that takes the next 2 parameters as the path of the file to upload/copy/rsync and the destination.

$ test-function -d {local-path} {destination}

If the first parameter is not -u (or it is -d), then execute a function that takes the next 2 parameters as the path of the file to download/copy/rsync (given that I'm at the current folder) and the destination.

I've found answers that suggest the solution here and here. However, my function in my .bash_profile returns errors like this:

function test_func {
    local a="$1"
    local a="$2"

    if ( a == "-u" ); then
        echo "This means upload"
    else
        echo "This means download"
    fi
}

alias test-function="test_func"

Then:

$ test-function -u
-bash: a: command not found
This means download
$ test-function -d
-bash: a: command not found
This means download

If I change the code to:

if [[a == "-u"]]; then
...

This happens:

$ test-function -u
-bash: [[a: command not found
This means download

If I change the code according to one of the answers I found:

if ((a == "-u")); then
...

This happens:

line 53: syntax error near unexpected token `}'

I guess this error is related to the double ((...)). How do you do it?

3

The error is here:

if ( a == "-u" ); then
    echo "This means upload"
else
    echo "This means download"
fi

The if construct expects an expression that can be evaluated to true or false. So, for example, a command (if ls; then echo yes;fi) or a test construct. You want to use a test construct but you're not using the test operator ([), you are using parentheses.

The parentheses just open a subshell. Therefore, the expression ( a == "-u" ) just means "run the command a with the arguments == and "-u" in a subshell. What you want is:

if [ "$a" = "-u" ]; then  ## you also need the $ here
    echo "This means upload"
else
    echo "This means download"
fi

Or, if you want to use the non-portable [[ ]] construct which works in bash, you need a space after the [[:

if [[ "$a" == "-u" ]]; then
    echo "This means upload"
else
    echo "This means download"
fi

You tried if [[a == "-u" ]] so the shell read [[a as a single command and failed.

Finally, the (( )) construct which, again is not portable, but does work in bash (and some other shells) is used for arithmetic evaluations. From man bash:

  ((expression))
          The  expression is evaluated according to the rules described below under
          ARITHMETIC EVALUATION.  If the value of the expression is  non-zero,  the
          return  status  is  0; otherwise the return status is 1.  This is exactly
          equivalent to let "expression".

So this isn't something you would want to use in this context.Putting all this together, you want something like this:

function test_func {
    local a="$1"

    if [ "$a" = "-u" ]; then
        echo "This means upload"
    else
        echo "This means download"
    fi
}

alias test-function="test_func"
  • Note that the standard [ syntax is [ a = -u ] (or [ "$a" = -u ] if the intention was to check the value of the a variable which would make more sense). The [ builtin of bash and a few other shells do support both = and == though. – Stéphane Chazelas Nov 1 '18 at 14:30
0

Try to use official syntax and use [ .... ] for the test calls.

  • ( ... ) creates a sub-shell

  • (( )) is a ksh specific internal arithmetic expression that likes numbers instead of -u

  • ((...)) is also supported (with variations) by bash and zsh and have been for decades so it's no longer ksh-specific. Note -u is fine, that's like (-1 * ${u:-0}), those " characters are a problem though. – Stéphane Chazelas Nov 1 '18 at 14:27
  • Well, it has been introduced in ksh88 and at that time there have been neither bash nor zsh;-) – schily Nov 1 '18 at 14:29
  • ((...)) is indeed originally a ksh extension (long before ksh88 btw), but is no longer ksh-specific, which is the point I was making. – Stéphane Chazelas Nov 1 '18 at 14:48
  • Well I mention it because some people usually call things like that a bashism. – schily Nov 1 '18 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.