Find the answer to your Linux question:
Results 1 to 9 of 9
Hey, folks. I've been using Linux for a while now, and I'm just dipping my toe into bash shell scripts, after flirting with them on and off for a while. ...
  1. #1
    Just Joined! Exocet's Avatar
    Join Date
    Oct 2009
    Posts
    6

    Unhappy [SOLVED] Simple shell script conundrum

    Hey, folks. I've been using Linux for a while now, and I'm just dipping my toe into bash shell scripts, after flirting with them on and off for a while. Apart from this, my only experience with programming anything is some batch files in the old DOS days.

    So I'm having a problem with the logic of shell scripting right now, and this is the problem. This script executes perfectly fine, and is a very simple matter indeed:

    Code:
    #!/bin/bash
    
    #evaluates whether the first argument on commandline is a directory
    #if false, set bgfolder to default directory
    if [ -d "$1" ]; then
        ${bgfolder=$1}
    else
        ${bgfolder=$HOME/Pictures/custom_backgrounds/1680}
    fi
    #print result to stdout
    echo "$bgfolder"
    
    exit 0
    The last echo command is just a test for the snippet, of course. It works this way in a larger script that changes my wallpaper automatically according to a random sort through a directory. It works well. But of course I need to be able to exploit functions to make use of a script of considerable size, so I tried this:

    Code:
    #!/bin/bash
    
    function pix_dir
    {
    #evaluates whether the first argument on commandline is a directory
    #if false, echo default directory
    if [ -d "$1" ]; then
        ${bgfolder=$1}
    else
        ${bgfolder=$HOME/Pictures/custom_backgrounds/1680}
    fi
    #print result to stdout
    echo "$bgfolder"
    }
    
    pix_dir
    
    exit 0
    Now, theoretically, this should do the same thing as the first example, but it passes over the first portion of the if statement and sets the variable to the default picture folder.

    Can anyone tell me why this might bet the case? I've tried unquoting the $1 parameter in the conditional statement, and attempted less elegant means of directory testing (e.g. [ $1 != */* ]). These do not work inside a function either.

    Any ideas?

  2. #2
    Linux Guru
    Join Date
    Nov 2007
    Posts
    1,695
    It looks like you cannot get to the command line args directly from inside the function. A simple test would be to echo the $1 variable in the function - it is likely unset.

    Try declaring the variable first - which is a good scripting practice.
    Code:
    #!/bin/bash
    
    FIRST_ARG=$1
    
    function (
    #Test if FIRST_ARG is a dir
    )
    
    exit
    Bash Scripting Guide

  3. #3
    Just Joined! Exocet's Avatar
    Join Date
    Oct 2009
    Posts
    6
    Thanks for your quick reply.

    Actually, I think I tried that earlier, but I gave it another go:

    Code:
    #!/bin/bash
    
    bgfolder=$1
    
    function pix_dir
    {
    #evaluates whether the first argument on commandline is a directory
    #if false, echo default directory
    if [ -d "$1" ]; then
        ${bgfolder=$1}
    else
        ${bgfolder=$HOME/Pictures/custom_backgrounds/1680}
    fi
    #print result to stdout
    echo "$bgfolder"
    }
    
    pix_dir
    
    exit 0
    Well, when I tested it with the root directory, it accepted the argument, echoing "/", but it wouldn't return the default directory when I typed something apart from a directory. It just gave me the $1 argument back, even if it was a random string. Where I'm trying to get to is for it to go to default for anything other than a directory for argument 1, even if there is no argument 1, which in this case the code returns a blank line instead.

    My 'set -x' output looks like this:

    Code:
    + pix_dir
    + '[' -d '' ']'
    + hjkhkj
    /home/user/bin/walltest_func.sh: line 16: hjkhkj: command not found
    + echo hjkhkj
    hjkhkj
    And when I actually provide a directory, it shows this:

    Code:
    + pix_dir
    + '[' -d '' ']'
    + /
    /home/user/bin/walltest_func.sh: line 16: /: is a directory
    + echo /
    /
    
    exit 0
    + exit 0
    Thanks for looking...

  4. #4
    Linux Guru
    Join Date
    Nov 2007
    Posts
    1,695
    You will need to review your script more closely...

    Code:
    /home/user/bin/walltest_func.sh: line 16: hjkhkj: command not found
    Assuming you put in that garbage as the "argument", you have a variable stated in the script such that bash is trying to execute it as a command.

  5. #5
    Just Joined! Exocet's Avatar
    Join Date
    Oct 2009
    Posts
    6
    Yes, I was trying to get the script to ignore anything other than a directory, even a blank line or random string, which is what I gave it at the commandline. It was intentionally not a real command. Perhaps the directory evaluation isn't designed to handle this, although it seemed reasonable at the time. Do you have a suggestion for getting this done?

    My purpose, ultimately, is to be able to have a default directory for the sort, but be able to add a directory to the script's link for evaluation when I execute it from a gnome-panel. This works without the function exactly as I wished, but not with the function.
    Last edited by Exocet; 10-13-2009 at 05:16 AM. Reason: changed "shell's" to "script's"

  6. #6
    Linux Guru
    Join Date
    Nov 2007
    Posts
    1,695
    Code:
    #!/bin/bash
    
    TEST_DIR="$1"
    cd /	# Change to / to give context
    
    if [ -d "$1" ]; then
    	echo "Yeehaw"
    else
    	echo "Better luck next time"
    fi
    
    exit 0
    Works fine for me. You need to either always use a full path, or account for a relative path.

    Code:
    /tmp/junk.sh /
    Yeehaw
    
    /tmp/junk.sh askdasd
    Better luck next time
    
    /tmp/junk.sh media
    Yeehaw
    
    /tmp/junk.sh media/cdrom
    Yeehaw
    
    /tmp/junk.sh media/askjdasj
    Better luck next time
    ** Sorry, I'm done. Good luck with your script.

  7. #7
    Just Joined! Exocet's Avatar
    Join Date
    Oct 2009
    Posts
    6
    Thanks for your help! I appreciate it. Later...

  8. #8
    Linux Guru
    Join Date
    Nov 2007
    Posts
    1,695
    Added one thing:

    Code:
    #!/bin/bash
    
    TEST_DIR="$1"
    cd /	# Change to / to give context
    
    if [ -d "$TEST_DIR" ]; then
    	BGFOLDER="$TEST_DIR"
    	echo "Yeehaw, BGFOLDER is $BGFOLDER"
    else
    	BGFOLDER="/some/sorry/folder"
    	echo "Better luck next time - BGFOLDER is $BGFOLDER"
    fi
    
    exit 0
    Code:
    /tmp/junk.sh media/cdrom
    Yeehaw, BGFOLDER is media/cdrom
    
    /tmp/junk.sh media/askjdasj
    Better luck next time - BGFOLDER is /some/sorry/folder

  9. #9
    Just Joined! Exocet's Avatar
    Join Date
    Oct 2009
    Posts
    6
    Excellent! Knowledge and experience to the rescue!

    That last construction did it, thanks. Been chewing this over for a day or two now, and I never thought of assigning the variables in that way.

    From either no argument or random string, now:
    Code:
    + pix_dir
    + '[' -d '' ']'
    + bgdir=/home/user/Pictures/custom_backgrounds/1680
    + echo /home/user/Pictures/custom_backgrounds/1680
    /home/user/Pictures/custom_backgrounds/1680
    
    exit 0
    + exit 0
    Thank you.

    And I appreciate the heads-up on the tutorial site as well.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...