Escribí un script bash para verificar varias configuraciones en un sistema, pero obtengo resultados diferentes dependiendo de si se ejecuta desde la línea de comandos directamente o desde el script. Aquí está el comando:
bt_discoverable=$(system_profiler SPBluetoothDataType | grep Discoverable)
Si deshabilito detectable en el bluetooth y luego hago eco de la variable en la línea de comando, obtengo el resultado esperado:
Discoverable: No
Pero si me hago eco inmediatamente después de ejecutar el mismo comando desde un script bash, obtengo
Discoverable: Yes
El script eleva sus privilegios a través de una función de sudo interna, así que comenté el bloqueo para esa función y ejecuté el script nuevamente. Esta vez, las cosas funcionaron como deberían. Aquí está la función de elevación:
RunAsRoot()
{
if [[ "${USER}" != "root" ]] ; then
echo
echo
echo "*** Type the password for ${USER} and press ENTER ***"
echo
sudo $1 && exit 0
fi
}
RunAsRoot $0
Esta función es lo primero que ejecuta el script, por lo que la posición del código es un problema.
¿Por qué la ejecución en un (sub) shell de privilegios elevados causa este problema? ¿El problema es Terminal, Bash u otra cosa que desconozco?
~/Library/Preferences/ByHost/com.apple.BlueTooth.<uuid>
, es posible que el usuario raíz cree su propio archivo BlueTooth temporalmente mientras está en la subshell, y su script verifica ese valor en lugar del usuario que inició sesión en OS X completo. Espero que tenga sentido, y Es solo una suposición de mi parte. :) ¿Qué cosas en tu script requieren root? ¿Especialmente si solo está comprobando los valores de system_profiler?Respuestas:
La diferencia proviene del cambio en el entorno de shell una vez elevado. No estoy seguro de cómo escribiría un script que explicaría este cambio fácilmente, pero la respuesta a mi pregunta original es que debe ser consciente de tales diferencias cuando eleva los privilegios.
Gracias a "gracias" por esta pista. Finalmente publiqué esto como respuesta, ya que no lo hicieron durante algunas semanas.
fuente
Esta es mi solución
sudoMe
se elevarároot
llamando nuevamente al script.doAsRoot
deben comprobarse$USER == root
, de lo contrario se ejecutará en la primera llamada del script como invocación de $ USER.sudoBack
se elevará usandosudo -k
discover
ahora se ejecutarán como primero$USER
Si invocamos como root como en la respuesta, no hay forma de que IMHO regrese
sudo -k
en ninguna parte del script. Lo probé, pero no pude encontrar ninguno ;-)fuente