Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict shell options to a function using `local -`?

Tags:

bash

The BASH man page for local says

local [option] [name[=value] ... | - ]
    […] If name is ‘-’, the set of shell options is made local to the 
    function in which local is invoked: shell options changed using the
    set builtin inside the function are restored to their original
    values when the function returns.

So based on this information, using local -, I should be able to use set -x inside of a function to enable trace output. When the function ends, the trace output would be disabled.

#!/bin/bash
foo() {
  local -
  set -x
  ... # this code is shown in trace output
}

# trace output is disabled
foo
# trace output should be disabled here

This does not work. When running the script, I get the error message

line 3: local: '-': not a valid identifier

and after the foo function returns, the trace output is still enabled for the remainder of the script.

I've tried this under BASH 4.4 on OSX and Ubuntu and BASH 3.2 on SLES.

like image 767
Insomniac Software Avatar asked Sep 29 '17 02:09

Insomniac Software


1 Answers

According to the Bash release log, local - is a new feature of Bash 4.4. I suspect that you likely do have Bash 4.4 installed on your machine but have not yet set it as your login shell and/or it is not located at the path /bin/bash that you specified in your shebang.

You can verify this with:

$ echo "$BASH_VERSION" 

4.4.12(1)-release

Depending on where you have installed Bash 4.4, you can upgrade and use this feature with:

##########################################
# OSX: Bash 4.4 installed via HomeBrew
##########################################

# Add the new shell to the list of allowed shells
echo /usr/local/bin/bash | sudo tee -a /etc/shells

# Change to the new shell
chsh -s /usr/local/bin/bash  

You will also need to use the correct shebang path. Good news is that if you have already set Bash 4.4 as your login shell (above), then you can simply use:

#!/usr/bin/env bash

If you find that you do not have Bash 4.4 installed, here is a simple guide to upgrade to Bash 4.4 on OSX.

Even the new 2017 MacBook Pro models ship with the old Bash 3.2. Unless you have manually upgraded your user bash login shell, you will not have Bash 4.4 and not have the local - feature.

like image 85
Travis Clarke Avatar answered Oct 26 '22 23:10

Travis Clarke