2

I have this:

function abash {
    if [[ -v $1 ]]
        then
            atom ~/Shell/$1.sh
        else
            atom ~/.bashrc
    fi
}

in my ~/.bashrc file, so as to make it easier to use Atom to edit my bash scripts, now the problem is that [[ -v $1 ]] is meant to be checking whether the input $1 exists but it does not appear to be, as even when I provide a valid input (e.g., running abash cd where ~/Shell/cd.sh is a file I want to edit) abash opens up ~/.bashrc. How do I fix this problem? Where did I get the idea for the [[ -v $1]] test? This answer.

3

bash conditional expression -v var check if shell variable named var is set.

When using [[ -v $1 ]], you actually checked whether a variable named by content of $1 was set. In your example, it means $cd, which was never set.

You can simply check if $1 is non-empty string, using -n:

function abash {
    if [[ -n "$1" ]]
        then
            atom ~/Shell/"$1.sh"
        else
            atom ~/.bashrc
    fi
}

Note that var must be a shell variable for -v var work. [[ -v 1 ]] will never work because 1 is denoted for positional parameter.

  • Still isn't working I'm afraid. It still keeps opening up ~/.bashrc when I run abash cd. If you're wondering whether I'm forgetting to source (source ~/.bashrc) it, don't, as I've got another function sbash that does that for me and I keep running it whenever I make changes to my bash scripts. – BH2017 Oct 28 '15 at 5:02
  • @BrentonHorne: What's sbash look like? how did you run it? – cuonglm Oct 28 '15 at 5:05
  • Even with the quotation marks ("") around $1.sh I'm afraid abash cd still keeps opening up ~/.bashrc – BH2017 Oct 28 '15 at 5:07
  • 1
    @cas: You don't need quote in new test [[ ... ]]. – cuonglm Oct 28 '15 at 6:40
  • 1
    ah, that's right. but it doesn't matter. always quote variables unless you are deliberately relying on auto-splitting by $IFS. even when it's not a syntax error, it's a bug waiting to happen. e.g. try passing a single arg like 'two or more words' or 'filename with a space in it' to that function. – cas Oct 28 '15 at 6:44
4

I'm not sure why this fails, but there are (at least) two other possible options. Instead of [[ -v $1 ]], you could use either of the following.

Check that the number of arguments is more than zero.

[[ $# > 0 ]]

Check that the first argument is not empty.

[[ $1 != '' ]]
  • It's quite unpleasant that UL treats the # here as command start. – Arthur2e5 Oct 28 '15 at 5:15
  • My apologies, I just tested your answer and it is equally valid as cuonglm's, if I could accept both of your answers I would. – BH2017 Oct 28 '15 at 5:17
  • @Arthur2e5 Fixed! :D – Sparhawk Oct 28 '15 at 5:19
  • @BrentonHorne No worries! cuonglm explained why it failed, so on that basis it's a better answer anyway. And he beat me by 5 minutes. ;) – Sparhawk Oct 28 '15 at 5:19
  • Couldn't you use [ $# > 0 ] just as well and have it portable? – Wildcard Oct 28 '15 at 6:53
1

What needs to be in the test is the name of the var, a tag name, if you wish. To test the variable a, you do not do `[[ -v $a ]], you do:

[[ -v a ]]

However, there is no way (AFAIK) to test positional parameters with -v because, in essence, positional parameters have no name. Or, if you wish, they are numbers, and the test does not work with a number.

So, you need to test the var directly without the help of -v as this:

[[ ${1:+present} ]]

Also:

You should quote your var expansions.
I prefer to use $HOME, instead of the tilde. It allows quoted strings.

abash() {
    if [[ ${1:+present} ]]
        then
            atom "$HOME/Shell/$1.sh"
        else
            atom "$HOME/.bashrc"
    fi
}

The answer is similar to this but please take note of the : that I included to make it work correctly.

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.