¿Hay un comando de una línea para hacer que chmod sea interactivo?

24

Estoy buscando algo como:

ls | ask_yes_no_for_each_file | chmod +x the_files_approved

O sintaxis similar.

También podría funcionar en otros comandos para los que desea confirmación individual.

Harvey
fuente

Respuestas:

45

Esto hace lo que estás buscando:

find . -maxdepth 1 -type f -print0 | xargs -L1 -p0 chmod +x

Esto se utiliza en findlugar de lsporque, en general, la salida de análisis lsno es confiable . Este formulario, findsin embargo, funcionará con nombres de archivo incluso si contienen nuevas líneas u otros caracteres difíciles.

Explicación

  • find . -maxdepth 1 -type f -print0

    Esto selecciona los archivos. Esto se puede personalizar utilizando cualquiera de las muchas opciones de búsqueda. La opción print0le dice findque imprima los nombres de los archivos en una lista separada por nulos. Este es el único confiable para transmitir listas de nombres de archivos.

  • xargs -L1 -p0 chmod +x

    Esto toma la lista de nombres de archivos separados por nulos generados por findy aplica su comando a ellos.

La -L1opción le indica xargsque trabaje solo con un nombre de archivo a la vez. La -popción le indica xargsque solicite aprobación antes de continuar. La -0opción le indica xargsque use el carácter nulo como delimitador entre los nombres de archivo.

[No tenía conocimiento de la -popción xargshasta que @kwan lo señaló.]

John1024
fuente
Puede hacer que el findcomando POSIX sea compatible utilizando -exec printf '%s\0' {} +. Sin embargo, no creo que haya alguna manera de hacer que todo sea compatible con POSIX.
l0b0
Esta sintaxis me da una advertencia find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.por lo que funciona con el -maxdepth 1antes de que el -type f, como: find . -maxdepth 1 -type f -print0 | xargs -L1 -p0 chmod +x.
Harvey
@Harvey Tienes razón: actualicé la respuesta para eliminar esa advertencia.
John1024
25

Puedes usar xargs.

p.ej:

ls|xargs -I path -p chmod +x path

Opción -p: Pregunte al usuario si debe ejecutar cada línea de comando y leer una línea desde el terminal. Solo ejecute la línea de comando si la respuesta comienza con 'y' o 'Y'.

Kwan
fuente
1
+1 Me gusta tanto tu uso xargs -pque lo copiaré.
John1024
1
¡Perfecto! Y una forma muy simple de hacer que la mayoría de los comandos sean interactivos. Gracias.
Harvey
21
No analizar ls.
Kroltan el
@Kroltan: ¿por qué alguien usaría una nueva línea en un nombre de archivo?
nbubis
1
@nbubis Puede suceder: vaya a una terminal y escriba touch "a very long file namey presione enter. Vea la continuación de la línea y simplemente escriba la cotización de cierre y presione enter nuevamente. tadaa, nueva línea en el nombre del archivo. Por flojera para volver a escribir un nombre de archivo largo.
Kroltan