Tengo alrededor de 10 php.ini
archivos en mi sistema, ubicados por todas partes, y quería examinarlos rápidamente. Intenté este comando:
locate php.ini | xargs vi
Pero vi
me advierte Input is not from a terminal
y luego la consola comienza a ponerse realmente extraña, después de lo cual necesito presionar :q!
para salir vi
y luego desconectarme de la sesión ssh y volver a conectar para que la consola vuelva a funcionar normalmente.
Creo que entiendo lo que está sucediendo aquí: básicamente, el comando no ha terminado cuando se vi
inició, por lo que tal vez el comando no haya terminado y vi
no piense que el terminal está en modo normal.
No tengo ni idea de cómo arreglarlo. He buscado en Google y también en unix.stackexchange.com con mala suerte.
reset
para restablecer su terminal cuando se arruina (no tiene que desconectarse de la sesión ssh).Respuestas:
Nota: esto tendrá problemas si las rutas de sus archivos tienen espacios, pero es funcionalmente equivalente a su comando.
Esta próxima versión manejará los espacios correctamente, pero es un poco más complicada (las nuevas líneas en los nombres de los archivos aún lo dividirán)
Explicación:
Lo que sucede es que los programas heredan sus descriptores de archivo del proceso que los generó.
xargs
tiene su STDIN conectado al STDOUT delocate
, por lo quevi
no tiene idea de en qué consiste realmente el STDIN original.fuente
xargs
para que no se pueda hacer directamente con el shell (ofind
). Sin embargo, puedo pensar en casos en los que sería la mejor solución. Entonces, siempre y cuando comprenda lo quexargs
está haciendo, cómo divide los argumentos, cómo ejecuta el programa, etc., y si lo está utilizando correctamente, diría que lo haga :-P... | awk '{print $3}' | xargs | sed -e 's/ /+/g' | bc
(para sumar todos los valores del campo 3). o consed -e 's/ /|/g'
para construir una expresión regular. y sí, como cualquier herramienta, necesita saber cómo usarla y cuáles son sus limitaciones y advertencias.vi $(...)
enfoque también tiene un problema con los comodines en los shells que no seanzsh
.xargs
enfoque al lado del problema del espacio en blanco, los nombres de archivo con comillas simples, comillas dobles y barras inclinadas invertidas también son un problema.Esta pregunta ya se hizo en el foro de Superusuario.
Citando la respuesta de @grawity a esa pregunta:
Esto se menciona en las páginas del manual para xarg. Desde OSX / BSD:
Por lo tanto, en OSX, puede usar el siguiente comando:
Si bien no hay un cambio directo en la versión de GNU, este comando funcionará. (Asegúrese de incluir la
dummy
cadena, de lo contrario, soltará el primer archivo).Las soluciones anteriores son cortesía de Jaime McGuigan en SuperUser . Agregándolos aquí para cualquier visitante futuro que busque este error en el sitio.
fuente
xargs sh -c 'emacs "$@" < /dev/tty' emacs
lo que, según ellos, es una alternativa más flexible y portátil (aunque es divertido que GNU prefiera la portabilidad a las características :).Con GNU
findutils
y un shell con soporte para la sustitución de procesos (ksh, zsh, bash), puede hacer:La idea es pasar la lista de archivos a través de un en
-a filename
lugar de stdin. El uso-0
asegura que funcione independientemente de qué caracteres o no caracteres puedan contener los nombres de archivo.Con
zsh
, podrías hacer:(donde
0
está el indicador de expansión de parámetros para dividir en NUL).Sin embargo, tenga en cuenta que, al contrario de
xargs -r
eso, todavía se ejecutavi
sin argumento si no se encuentra ningún archivo.fuente
¿Editar múltiples php.ini dentro del mismo editor?
Tratar:
vim -o $(locate php.ini)
fuente
Este error ocurre cuando se invoca vim y está conectado a la salida de la tubería anterior, en lugar del terminal y está recibiendo una entrada inesperada diferente (como NUL). Lo mismo sucede cuando ejecuta:
vim < /dev/null
por lo que elreset
comando en este caso ayuda. Esto se explica bien por la gravedad en el superusuario .En Unix / OSX puede utilizar
xargs
con-o
los parámetros, tales como:En Linux intente la siguiente solución:
Alternativamente, use GNU en
parallel
lugar dexargs
forzar la asignación de tty, por ejemplo:Nota:
parallel
en Unix / OSX no funcionará ya que tiene diferentes parámetros y no es compatible con tty.Muchos otros comandos populares también proporcionan asignación de pseudo-tty (como
-t
enssh
), así que busca ayuda.Alternativamente, use
find
para pasar nombres de archivo para editar, por lo que no es necesarioxargs
, solo use-exec
, por ejemplo:fuente
El
IFS
truco de @ Patrick solo es necesario para conchas tontas comobash
yzsh
.fish
divide la cadena en líneas nuevas de forma predeterminada.Y que Dios nos ayude a todos si uno de nosotros tiene un archivo con una nueva línea en su nombre. Después de 17 años usando Linux, no lo he visto ni una sola vez. Solo me molestaría en admitir nombres de archivo con nuevas líneas para los scripts que tienen que funcionar sin importar qué, pero los scripts como ese probablemente no se ejecutan vim de forma interactiva.
fuente
zsh
se divide en SPC, TAB, NL y NUL por defecto. Lo que no hace en comparación conbash
es realizar una observación global del resultado para que los caracteres comodín en los nombres de archivo no sean un problema. Enzsh
, haríasIFS=$'\0'; vi $(locate -0 php.ini)
o como mostré en mi respuestavi ${(0)"$(locate -0 php.ini)"}
para un operador de división explícito. También tenga en cuenta tcsh'svi "`locate php.ini`"
$ f='not there'<ret>$ ls $f<ret>
pero esto no: lsecho not there
. OK parece que necesito actualizar esto un poco.ls "$(echo test; echo other test)"
. Solo el pescado hace lo correcto.$IFS
o mediante operadores explícitos (f
y0
banderas de expansión de parámetros). Para nombres de archivo arbitrarios, dividir por palabra o dividir por línea es igualmente incorrecto , debe dividir en NUL o analizar algo de codificación, lo quefish
no puede hacer. Enzsh
, eso esIFS=$'\0'; ls -ld -- $(printf '%s\0' "$file1" "$file2")
ols -ld -- ${(0)"$(printf '%s\0' "$file1" "$file2")"}
Una forma rápida de hacerlo, en el supuesto que se puede garantizar ninguna de las rutas de archivos contienen SPC, TAB, NL,
*
,?
,[
caracteres (también\
y{...}
en algunas conchas) es el uso de copias de las garrapatas (también conocido como acento grave) para ejecutar un comando antes otro comando corriendo.P.ej
El comando contenido dentro de los ticks posteriores se ejecutará primero. La salida del comando contenido se ejecuta luego mediante el comando indicado antes de los ticks de retroceso.
Por ejemplo, en la línea anterior, el
find / -type f -name 'php.ini'
comando se ejecutará primero, enviará la salida y luegovi
se ejecutará según el resultado de split + glob aplicado a esa salida.fuente
$(find ...)
en su lugar.vi
usar este método. Es muy posible que se rompa en nuevas líneas o espacios, dependiendo de cómovi
esté leyendo y ejecutando la salida.