1

I am trying to create a reverse function in Bash where it will reverse either a directory or just an array of items as a parameter using a main function and a reverse function. I believe that my main function is messed up or that I cannot invoke the reverse function that I have created. I am not that familiar with Bash either.

#!/bin/bash
function reverse(){
    input=$1     #1st parameter
    copy=${input}
    len=${#copy}
    for((i=$len-1;i>=0;i--)); do
        if [ $i = "[" ]; then
             continue
        fi
        rev="$rev${copy:$i:1}"
    done
    echo "var: $var, rev: $rev"
}

function main(){
    arr=( tiger lion bear )
    mydir = $arr
    reverse $mydir
    echo $reverse
    # should print: bear lion tiger
}

main
9
  • @Palec the output should be a reversal of each of those members in the array or directory. So for example if you had "tiger lion bear" it would return "bear lion tiger" . I don't need to reverse the words it seems, but re-position them? Commented Sep 22, 2014 at 0:59
  • 3
    You must not have spaces around the = in variable assignment in shell. You have them in main when assigning to mydir. Commented Sep 22, 2014 at 1:08
  • @Palec thank you for pointing that out. It is working now. However, I just need to figure out how to reverse them in order and not by character. Can you store them in an array and print out positions backwards in bash? Commented Sep 22, 2014 at 1:16
  • You are storing them in an array, and yes you can index them directly, and yes that means you can get the length of the array and fill a new array in reverse. Commented Sep 22, 2014 at 1:36
  • @Palec that was a general question that was not directed at you to do it, but just in general since I am not familiar with bash and I am just seeking more information so I can understand and figure it out myself and learn. I was not asking for anyone to do this problem for me, but rather some tips or an explanation at some things. Do you have any resources or links where I can reference bash that you find useful? Not the bash reference manual either. Thanks Commented Sep 22, 2014 at 1:55

1 Answer 1

3

There are two big problems with your code:

  1. When assigning to mydir, you probably want to copy the whole array. But you assign $arr, which is the same as assigning only the first element, ${arr[0]}. Quoting Arrays section of man bash:

    Referencing an array variable without a subscript is equivalent to referencing with a subscript of 0.

    You should use mydir=( "${arr[@]}" ) to copy the array and then a similar construct to pass the whole array to the reverse function. But you don’t have to copy the array at all, this main is sufficient:

    function main(){
        arr=( tiger lion bear )
        reverse "${arr[@]}"
    }
    
  2. Your implementation of reverse reverses letters in its first parameter, i.e. the first item of arr array, as it is called now. You should reverse the array instead. It will be stored in parameters of the function, the @ variable. You can get all the parameters of your function as a params array via params=( "$@" ).

The second point strongly hints me that you have no idea what you are doing and you just copy-pasted parts of the script from somewhere. I will not write the code for you. It is really easy to do if you know the basics of Bash. If you don’t, go learn them. You will learn nothing by copy-pasting ad-hoc snippets from Stack Overflow or other sites. Next time, you would come to ask virtually the same question again. We are not here to make your homework for you, we are here to teach you.

There are also several minor issues, but still pretty severe in terms of functionality.

  • You must not have spaces around the = in variable assignment in shell. You have them in main when assigning to mydir. This is why Bash probably prints an error saying that is cannot find any command named mydir. Each shell splits the command line into words and treats the first word as command name.

  • Your reverse function copies input variable needlessly – unless you really want to print the original value at the end as you do now, of course. But then, I would rather copy the content to a variable named original and work on the input variable, because then the intent would be easier to understand.

  • Everywhere you expand a variable in shell, you should expand it inside double quotes, unless you have a good reason to do otherwise and you know what you are doing. If you expand it outside double quotes, you are going to get into trouble with escaping errors. Double quotes protect most special characters inside from being interpreted by the shell, only allowing variable, command, arithmetic and history expansion.

  • In the loop in reverse, i is supposed to contain a number. It is nonsense to test if for string equality to [. That condition is always false.

  • You never initialize var variable, but you use its value in the echo statement at the end of reverse body.

    You also do not specify value of rev variable before you first use it. As all variables are empty by default and you use reverse only once, this is not an issue, but it still is not a good practice.

    Another variable without initialization is reverse at the last line of main. Function call in shell returns only status, pretty much like any other command. You can modify a (global) variable inside the function, but you don’t do that. The echo command at the end of main is thus useless.

I already told you enough to figure out the correct implementation of reverse even if you are a shell beginner. If you read the Arrays section of Bash manual again, everything should be clear. If it is not, comment and I’ll try to give you more guidance.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks a ton for all of this detailed info without actually writing it for me. I am a beginner using bash and some syntax and methodology in here as opposed to other languages gets me tripped up from time to time. I really appreciate the detailed explanations though and for the reference manuals. OVerall, I just want to learn since it will benefit me in the long run for life, but I wanted to see if I was at least on teh right track in terms of what I wrote. Thanks again Palec!
You’re welcome. :-) I understand how difficult it is to code in shell, even in a modern one like Bash. If my answer solved your problem, consider accepting it (the ✓ next to the answer). If you find it useful, feel free to upvote it (unless you already have, of course).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.