Estoy tratando de usar find a echo 0 en algunos archivos, pero aparentemente esto solo funciona con sh -c :
find /proc/sys/net/ipv6 -name accept_ra -exec sh -c 'echo 0 > {}' ;
Pero usando sh -c con find -exec me hace sentir muy inquieto porque sospecho problemas de cotización. Jugué un poco con él y aparentemente mis sospechas estaban justificadas:
-
Mi configuración de prueba:
[email protected] ~ % cd findtest [email protected] ~/findtest % echo one > file with spaces [email protected] ~/findtest % echo two > file with 'single quotes' [email protected] ~/findtest % echo three > file with "double quotes" [email protected] ~/findtest % ll insgesamt 12K -rw-rw-r-- 1 martin martin 6 Sep 17 12:01 file with "double quotes" -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with 'single quotes' -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with spaces -
Usando
find -execsinsh -cparece funcionar sin problemas; no es necesario citar aquí:[email protected] ~ % find findtest -type f -exec cat {} ; one two three -
Pero cuando estoy usando
sh -c{}parece requerir algún tipo de cita:[email protected] ~ % LANG=C find findtest -type f -exec sh -c 'cat {}' ; cat: findtest/file: No such file or directory cat: with: No such file or directory cat: spaces: No such file or directory cat: findtest/file: No such file or directory cat: with: No such file or directory cat: single quotes: No such file or directory cat: findtest/file: No such file or directory cat: with: No such file or directory cat: double quotes: No such file or directory -
Las comillas dobles funcionan siempre que ningún nombre de archivo contenga comillas dobles:
[email protected] ~ % LANG=C find findtest -type f -exec sh -c 'cat "{}"' ; one two cat: findtest/file with double: No such file or directory cat: quotes: No such file or directory -
Las comillas simples funcionan siempre que ningún nombre de archivo contenga comillas simples:
[email protected] ~ % LANG=C find findtest -type f -exec sh -c "cat '{}'" ; one cat: findtest/file with single: No such file or directory cat: quotes: No such file or directory three
No he encontrado una solución que funcione en todos los casos. ¿Hay algo que estoy pasando por alto o estoy usando sh -c? en find -exec intrínsecamente inseguro?
Respuesta aceptada:
Nunca inserte {} en el código de shell! Eso crea una vulnerabilidad de inyección de comandos. Tenga en cuenta que para cat "{}" , no se trata solo del " caracteres, , ` , $ también son un problema (considere, por ejemplo, un archivo llamado ./$(reboot)/accept_ra )¹.
Aquí, le gustaría pasar los nombres de los archivos como argumentos separados a sh (no en el código argumento), y el sh secuencia de comandos en línea (el código argumento) para referirse a ellos usando parámetros posicionales:
find . -name accept_ra -exec sh -c 'echo 0 > "$1"' sh {} ;
O, para evitar ejecutar un sh por archivo:
find . -name accept_ra -exec sh -c 'for file do
echo 0 > "$file"; done' sh {} +
Lo mismo se aplica a xargs -I{} o zsh 's zargs -I{} . No escribas:
<list.txt xargs -I{} sh -c 'cmd > {}'
Lo cual sería una vulnerabilidad de inyección de comando de la misma manera que con find arriba, pero:
<list.txt xargs sh -c 'for file do cmd > "$file"; done' sh
Lo que también tiene la ventaja de evitar ejecutar un sh por archivo y el error cuando list.txt no contiene ningún archivo.
Con zsh los zargs , probablemente querrá usar una función en lugar de invocar sh -c :
do-it() cmd > $1
zargs ./*.txt -- do-it
Tenga en cuenta que en todos los ejemplos anteriores, el segundo sh anterior entra en el $0 del script en línea . Deberías usar algo relevante allí (como sh o find-sh ), no cosas como _ , - , -- o la cadena vacía, como el valor en $0 se utiliza para los mensajes de error del shell:
$ find . -name accept_ra -exec sh -c 'echo 0 > "$1"' inline-sh {} ;
inline-sh: ./accept_ra: Permission denied
GNU parallel funciona de manera diferente. Con él, no quiero usar sh -c como parallel ya ejecuta un shell e intenta reemplazar {} con el argumento citado en la sintaxis correcta para el shell.
<list.txt PARALLEL_SHELL=sh parallel 'cmd > {}'