0

I wrote a bash script to verify various configs on a system, but I am getting different results depending on whether it is run from the command line directly or from the script. Here is the command:

bt_discoverable=$(system_profiler SPBluetoothDataType | grep Discoverable)

If I disable discoverable on the bluetooth and then echo the variable on the command line I get the expected result:

Discoverable: No

But if I echo it immediately after running the same command from a bash script, I get

Discoverable: Yes

The script does elevate its privileges through an internal sudo function, so I commented the block for that function out and ran the script again. This time, things worked as they should. Here is the elevation function:

RunAsRoot()
{
        if [[ "${USER}" != "root" ]] ; then
                echo
                echo
                echo "***  Type the password for ${USER} and press ENTER  ***"
                echo
                sudo $1 && exit 0
        fi
}
RunAsRoot $0

This function is the first thing the script runs, so the code position is a problem.

Why does running in an elevated privilege (sub)shell cause this issue? Is the problem Terminal, Bash, or something else I'm ignorant of?

  • 2
    I guess the subshell might cause the issue, since it's a subshell as root instead of the current user. Since the "Discoverable" boolean is stored in ~/Library/Preferences/ByHost/com.apple.BlueTooth.<uuid>, it's possible that the root user creates its own BlueTooth file temporarily while in the subshell, and your script checks that value instead of the user logged into full OS X. I hope that makes sense, and it's just a guess on my part. :) What things in your script require root? Especially if you're just checking system_profiler values? – thankyour May 6 '14 at 14:32
  • it's a bind script to verify that macs at schools have successfully been configured and bound to AD domain. dsconfigad requires it at least on some versions, even though this is an informational script only. – labyrinth May 6 '14 at 17:12
1

The difference comes from the change in shell environment once elevated. I'm not sure how you would write a script that would account for this change easily, but the answer to my original question is that you need to be aware of such differences when you elevate privileges.

Thanks to "thankyour" for this lead. I finally posted this as an answer since they didn't for some weeks.

0

This is my workaround

bt_discoverable=$(system_profiler SPBluetoothDataType | grep Discoverable)

sudoMe()
{
    if [[ "${USER}" != "root" ]]; then
    echo "inside...as: $USER"
    sudo $0 && sudoBack

    fi
}

doAsRoot(){
    if [[ "${USER}" == "root" ]]; then
        echo "this as $USER"
    fi
}

sudoBack(){
    if [[ "${USER}" == "root" ]]; then
        echo "reverse...from: $USER"
        sudo -k && exit 0
    fi
}

discover() {
    echo $bt_discoverable
}

sudoMe 
doAsRoot
sudoBack
discover
  1. sudoMe will elevate to root by calling the script again.
  2. All following functions like doAsRoot must check for $USER == root, otherwise will run in first call of script as invoking $USER.
  3. sudoBack will elevate down using sudo -k
  4. All following functions like discover will now run as first $USER

If we invoke as root like in the answer, there is no way IMHO back with sudo -k in any part of the script. I tested, but couldn't find any ;-)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .