1 votos

Cita el nombre de un archivo en un script que se le pasa chmod?

Estoy teniendo problemas para citar un nombre de archivo que se pasa finalmente a chmod. El guión fue escrito originalmente por SSH s StrictModes y authorized_keys, pero tuve que ampliarlo debido a una mala UMASK que provocó que algunos sistemas de archivos molestias. La secuencia de comandos que se encuentra debajo, y su producción de barcos cargados de:

chmod: /Users/<user>/Library/Application: No such file or directory
chmod: Support/TextMate/Managed/Bundles/HTML.tmbundle/Macros/Delete: No such file or directory
chmod: whitespace: No such file or directory
chmod: between: No such file or directory
chmod: tags.plist: No such file or directory
...
chmod: /Users/<user>/Library/Caches/com.operasoftware.Opera/Media: No such file or directory
chmod: Cache/index: No such file or directory
cut: stdin: Illegal byte sequence
...

Yo he probado un par de soluciones, pero ninguna de ellas ha ayudado. Traté de doble citando como ""$file"", pero el problema persistió. También probé la parte de atrás de las garrapatas (que son desalentados en este caso), pero el problema persistió.

El más cercano que tengo a la realidad citando fue el disfuncionales "\"""$file""\"". Pero, a continuación, chmod se quejó el nombre de archivo (con comillas) no era un verdadero archivo:

$ sudo ~/fix-perms.sh
chmod: "/Users/Shared/.localized": No such file or directory
chmod: "/Users/<user>/.CFUserTextEncoding": No such file or directory
chmod: "/Users/<user>/.lesshst": No such file or directory

¿Cómo puedo citar el nombre de archivo que sale de find que pasa en chmod? O ¿cómo puedo obtener chmod a tomar el nombre de archivo como un solo argumento?


$ cat ~/fix-perms.sh 
#!/bin/bash

# Directories
find /Users/* -type d -exec chmod 0700 {} \;
find /Users/Shared -type d -exec chmod 0777 {} \;

# Files
for file in `find /Users/* -type f`;
do
    if [ `file "$file" | cut -d":" -f 2 | grep -i -c executable` -eq 0 ];
    then
        `chmod 0600 "$file"`
    else
        `chmod 0700 "$file"`
    fi
done

for user in `ls -A /Users`;
do
    if [ -e "/Users/$user/.ssh/authorized_keys" ];
    then
        chmod 0600 "/Users/${user}/.ssh/authorized_keys"
    fi
done

3voto

mtklr Puntos 122

fwiw, find [options] -print0, cuando se utiliza en conjunción con canaliza a) xargs -0 [options], maneja los nombres de archivo con espacios, sin jugar con for bucles o IFS:

find /Users ! -path '/Users/Shared*' -type f -print0 | xargs -0 -I {} \
    bash -c 'if [[ "$(file -b --mime-type -- "{}")" = "application/x-mach-binary" ]]; then
                 chmod 700 "{}"
             else
                 chmod 600 "{}"
             fi'

1voto

jww Puntos 520

Yo era capaz de resolver el problema cambiando IFS a IFS=$(echo -en "\n\b") y no citando el nombre del archivo. IFS es Interna Separador de Campo, se utiliza (entre otros) para la palabra después de la división de shell expansiones, y se incluye un espacio de forma predeterminada.

He encontrado el IFS truco en nixCraft del Shell BASH: Bucle de Archivo Con Espacios en el nombre.

$ cat fix-perms.sh
#!/bin/bash

SAVED_IFS=$IFS
IFS=$(echo -en "\n\b")

# Directories
chmod 0755 /Users
find /Users/* -type d -exec chmod 0700 {} \;
find /Users/Shared -type d -exec chmod 0777 {} \;

# Files
for file in `find /Users/* -type f`;
do
    if [ `file "$file" | cut -d":" -f 2 | grep -i -c executable` -eq 0 ];
    then
        chmod 0600 "$file"
    else
        chmod 0700 "$file"
    fi
done

for user in `ls -A /Users`;
do
    if [ -e "/Users/$user/.ssh/authorized_keys" ];
    then
        chmod 0600 "/Users/${user}/.ssh/authorized_keys"
    fi
done

IFS=$SAVED_IFS

0voto

Michael Zhou Puntos 167

find puede manejar los espacios en los nombres de archivo. Su for loops están causando los problemas. Usted puede poner su lógica en múltiples find comandos. No todos los directorios en una carpeta inicio del usuario debe ser accesible sólo a ellos mismos. Público y Sitios de venir a la mente. Usted puede fijar por separado en otro comando buscar.

find /Users/* ! -path '/Users/Shared*'  -type d ! \( -name Public -o -name Sites \) -exec chmod 0700 {} +

El comando excluye el directorio Compartido junto con el Público y los Sitios de directorios, a continuación, cambia los permisos en los directorios restantes.

Usted puede utilizar + en su find declaraciones a tener find actuar como si se tratara xargs.

find /Users/Shared -type d -exec chmod 0777 {} +

Suponiendo que los archivos ejecutables en la carpeta inicio de un usuario son las aplicaciones que haces, entonces usted podría hacer esto.

find /Users/* ! -path '/Users/Shared*' type f ! perm -755 -exec chmod 0600 {} +

0voto

Nate Puntos 220

mtklr (y Patrix') solución funciona, pero me parece que es más fácil usar un while read bucle cuando se trata de un archivo de lista de find ... -print0:

find /Users '!' -path '/Users/Shared*' -type f -print0 |
    while IFS= read -d '' -r file; do
        if file "$file" | grep -iq ": .*executable"; then
            chmod 700 "$file"
        else
            chmod 600 "$file"
        fi
    done

read -d '' utiliza los valores null como un delimitador. También usé -r para evitar que se intenta analizar los escapes, y IFS= para evitar que el recorte de los espacios en blanco al final del nombre de archivo (y ya que es un prefijo a la read comando, sólo se aplica a uno y no tener que volver después).

Por CIERTO, yo también solía if ... | grep -q ... -- el -q dice grep no a la salida de nada, pero el estado de su salida sólo tendrá éxito si se encuentra al menos una coincidencia. Y desde if sólo pruebas el estado de salida del comando en ella, eso es todo lo que se necesita.

BTW, esta se basa principalmente en BashFAQ #20: ¿Cómo puedo encontrar y manipular de forma segura los nombres de archivo que contiene saltos de línea, espacios o ambos?. Recomiendo darle un vistazo...

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X