Tengo un script que hace varias cosas diferentes, la mayoría de las cuales no requieren privilegios especiales. Sin embargo, una sección específica, que he contenido dentro de una función, necesita privilegios de root.
No deseo requerir que todo el script se ejecute como root, y quiero poder llamar a esta función, con privilegios de root, desde el script. Solicitar una contraseña si es necesario no es un problema, ya que de todos modos es principalmente interactivo. Sin embargo, cuando trato de usar sudo functionx
, obtengo:
sudo: functionx: command not found
Como esperaba, export
no hizo la diferencia. Me gustaría poder ejecutar la función directamente en el script en lugar de dividirla y ejecutarla como un script separado por varias razones.
¿Hay alguna forma de hacer que mi función sea "visible" para sudo sin extraerla, encontrar el directorio apropiado y luego ejecutarlo como un script independiente?
La función se trata de una página en sí misma y contiene múltiples cadenas, algunas con comillas dobles y otras con comillas simples. También depende de una función de menú definida en otra parte del script principal.
Solo esperaría que alguien con sudo CUALQUIERA pueda ejecutar la función, ya que una de las cosas que hace es cambiar las contraseñas.
declare
también a ellas.Respuestas:
Admito que no hay una forma simple e intuitiva de hacer esto, y esto es un poco hackey. Pero, puedes hacerlo así:
O más simplemente:
Esto funciona para mi:
Básicamente,
declare -f
devolverá el contenido de la función, que luego pasará a enbash -c
línea.Si desea exportar todas las funciones desde la instancia externa de bash, cambie
FUNC=$(declare -f hello)
aFUNC=$(declare -f)
.Editar
Para abordar los comentarios sobre las citas, vea este ejemplo:
fuente
echo "Hello!"
es efectivamente el mismo queecho Hello!
(es decir, las comillas dobles no hacen ninguna diferencia para este comando de eco en particular). En muchas otras circunstancias, las comillas dobles en la función pueden romper elbash -c
comando.bash -xc
en lugar de sólobash -c
) y parece quebash
es lo suficientemente inteligente como para las cosas volver a citar en esta situación, incluso hasta el punto de sustituir las comillas dobles con comillas simples y cambiando'
a'\''
si es necesario. Estoy seguro de que habrá algunos casos que no puede manejar, pero definitivamente funciona para casos al menos simples y moderadamente complejos, por ejemplo, intentefunction hello() { filename="this is a 'filename' with single quotes and spaces" ; echo "$filename" ; } ; FUNC=$(declare -f hello) ; bash -xc "$FUNC ; hello"
declare -f
imprime la definición de la función de manera que bash pueda volver a analizarla, por lobash -c "$(declare -f)"
que funciona correctamente (suponiendo que la capa externa también sea bash). El ejemplo que publicó muestra que funciona correctamente: el lugar donde se cambiaron las comillas está en la traza , porque bash imprime trazas en la sintaxis de shell, por ejemplo, intentebash -xc 'echo "hello world"'
sudo yourFunction
se encuentra (de lo contrario, obtiene un error de segmentación de la recursión)El "problema" es que
sudo
borra el entorno (a excepción de un puñado de variables permitidas) y establece algunas variables en valores seguros predefinidos para proteger contra riesgos de seguridad. en otras palabras, esto no es realmente un problema. Es una característicaPor ejemplo, si configuró
PATH="/path/to/myevildirectory:$PATH"
ysudo
no configuró PATH en un valor predefinido, cualquier script que no especifique el nombre de ruta completo para TODOS los comandos que ejecuta (es decir, la mayoría de los scripts) se vería/path/to/myevildirectory
antes que cualquier otro directorio. Ponga comandos comols
ugrep
otras herramientas comunes allí y podrá hacer fácilmente lo que quiera en el sistema.La forma más fácil / mejor es volver a escribir la función como un script y guardarla en algún lugar de la ruta (o especificar la ruta completa al script en la
sudo
línea de comandos, lo que deberá hacer de todos modos a menos quesudo
esté configurado para permitirle ejecutar CUALQUIER comando como root) y hacerlo ejecutable conchmod +x /path/to/scriptname.sh
La reescritura de una función de shell como un guión es tan simple como el ahorro de los comandos dentro de la definición de función en un archivo (sin el
function ...
,{
y}
líneas).fuente
sudo -E
evita limpiar el medio ambiente.He escrito mi propia
Sudo
función bash para hacer eso, funciona para llamar a funciones y alias:fuente
Puedes combinar funciones y alias
Ejemplo:
entonces
sudo hello
funcionafuente
Aquí hay una variación en la respuesta de Will . Implica un
cat
proceso adicional , pero ofrece la comodidad de heredoc. En pocas palabras, es así:Si quieres más comida para pensar, prueba esto:
El resultado es:
Aquí tenemos la
menu
función correspondiente con la de la pregunta, que está "definida en otra parte del script principal". Si "en otro lugar" significa que su definición ya se ha leído en esta etapa cuandosudo
se ejecuta la función exigente , entonces la situación es análoga. Pero puede que aún no se haya leído. Puede haber otra función que aún activará su definición. En este casodeclare -f menu
tiene que ser reemplazado por algo más sofisticado, o todo el script corregido de una manera que lamenu
función ya esté declarada.fuente
menu
función se habría declarado antes de este punto, comof
se invoca desde un menú.Suponiendo que su script sea (a) autocontenido o (b) pueda obtener sus componentes en función de su ubicación (en lugar de recordar dónde está su directorio de inicio), puede hacer algo como esto:
$0
nombre de ruta para el script, use eso en elsudo
comando, y pase una opción que el script verificará, para llamar a la actualización de contraseña. Siempre y cuando confíes en encontrar el script en la ruta (en lugar de solo ejecutarlo./myscript
), deberías obtener un nombre de ruta absoluto$0
.sudo
ejecuta el script, tiene acceso a las funciones que necesita en el script.uid
y se dará cuenta de que se ejecutó como usuario raíz , y al ver que tiene la opción establecida para indicarle que actualice la contraseña, vaya y haga ese.Los scripts pueden repetirse en sí mismos por varias razones: el cambio de privilegios es uno de esos.
fuente