Tengo alrededor de 10 php.iniarchivos en mi sistema, ubicados por todas partes, y quería examinarlos rápidamente. Intenté este comando:
locate php.ini | xargs vi
Pero vime advierte Input is not from a terminaly luego la consola comienza a ponerse realmente extraña, después de lo cual necesito presionar :q!para salir viy 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 viinició, por lo que tal vez el comando no haya terminado y vino 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.

resetpara 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ó.
xargstiene su STDIN conectado al STDOUT delocate, por lo quevino tiene idea de en qué consiste realmente el STDIN original.fuente
xargspara 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 quexargsestá 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.xargsenfoque 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
dummycadena, 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' emacslo 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
findutilsy 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 filenamelugar de stdin. El uso-0asegura que funcione independientemente de qué caracteres o no caracteres puedan contener los nombres de archivo.Con
zsh, podrías hacer:(donde
0está el indicador de expansión de parámetros para dividir en NUL).Sin embargo, tenga en cuenta que, al contrario de
xargs -reso, todavía se ejecutavisin 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/nullpor lo que elresetcomando en este caso ayuda. Esto se explica bien por la gravedad en el superusuario .En Unix / OSX puede utilizar
xargscon-olos parámetros, tales como:En Linux intente la siguiente solución:
Alternativamente, use GNU en
parallellugar dexargsforzar la asignación de tty, por ejemplo:Nota:
parallelen 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
-tenssh), así que busca ayuda.Alternativamente, use
findpara pasar nombres de archivo para editar, por lo que no es necesarioxargs, solo use-exec, por ejemplo:fuente
El
IFStruco de @ Patrick solo es necesario para conchas tontas comobashyzsh.fishdivide 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
zshse divide en SPC, TAB, NL y NUL por defecto. Lo que no hace en comparación conbashes 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.$IFSo mediante operadores explícitos (fy0banderas 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 quefishno 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 luegovise ejecutará según el resultado de split + glob aplicado a esa salida.fuente
$(find ...)en su lugar.viusar este método. Es muy posible que se rompa en nuevas líneas o espacios, dependiendo de cómoviesté leyendo y ejecutando la salida.