webshell reversa que pentestmonkey con shell unix

reversa - Shell one liner para anteponer a un archivo



shell reversa con netcat (30)

Esta es probablemente una solución compleja .

Estoy buscando un operador simple como ">>", pero para anteponer.

Me temo que no existe Tendré que hacer algo como

mv myfile tmp cat myheader tmp > myfile

¿Algo más inteligente?


¿Por qué no simplemente usar el comando ed (como ya sugirió Fluffle aquí)?

ed lee todo el archivo en la memoria y realiza automáticamente una edición de archivo en el lugar!

Entonces, si su archivo no es tan grande ...

# cf. "Editing files with the ed text editor from scripts.", # http://wiki.bash-hackers.org/doku.php?id=howto:edit-ed prepend() { printf ''%s/n'' H 1i "${1}" . wq | ed -s "${2}" } echo ''Hello, world!'' > myfile prepend ''line to prepend'' myfile

Sin embargo, otra solución alternativa sería utilizar archivos abiertos como lo sugiere Jürgen Hötzel en Redirect output from sed ''s / c / d /'' myFile to myFile

echo cat > manipulate.txt exec 3<manipulate.txt # Prevent open file from being truncated: rm manipulate.txt sed ''s/cat/dog/'' <&3 > manipulate.txt

Todo esto podría ponerse en una sola línea, por supuesto.


ADVERTENCIA: esto requiere un poco más de trabajo para cumplir con las necesidades del OP.

Debería haber una manera de hacer que el enfoque sed por @shixilun funcione a pesar de sus dudas. Debe haber un comando bash para escapar del espacio en blanco al leer un archivo en una cadena sustituta sed (por ejemplo, reemplazar caracteres de nueva línea con ''/ n''. Los comandos de shell vis y cat pueden tratar caracteres no imprimibles, pero no espacios en blanco, así que esto no resolverá el problema de OP:

sed -i -e "1s/^/$(cat file_with_header.txt)/" file_to_be_prepended.txt

falla debido a las líneas nuevas sin formato en el script sustituto, que deben ir precedidas de un carácter de continuación de línea () y quizás seguido por un &, para mantener contentos al shell y al sed, como esta respuesta SO

sed tiene un límite de tamaño de 40K para comandos no globales de búsqueda-reemplazo (sin seguimiento / g después del patrón) por lo que es probable que evite los temibles problemas de desbordamiento del búfer de awk que advirtió anonymous.


Como sugiere Daniel Velkov, usa tee.
Para mí, esa es una solución inteligente simple:

{ echo foo; cat bar; } | tee bar > /dev/null


Con $ (comando) puede escribir la salida de un comando en una variable. Así que lo hice en tres comandos en una línea y sin archivo temporal.

originalContent=$(cat targetfile) && echo "text to prepend" > targetfile && echo "$originalContent" >> targetfile


Creo que esta es la variación más limpia de ed:

cat myheader | { echo ''0a''; cat ; echo -e "./nw";} | ed myfile

como una función:

function prepend() { { echo ''0a''; cat ; echo -e "./nw";} | ed $1; } cat myheader | prepend myfile


Cuando empiezas a intentar hacer cosas que se vuelven difíciles en shell-script, te sugiero encarecidamente buscar reescribir el script en un lenguaje de scripting "apropiado" (Python / Perl / Ruby / etc)

En cuanto a anteponer una línea a un archivo, no es posible hacerlo a través de tuberías, como cuando haces algo como cat blah.txt | grep something > blah.txt cat blah.txt | grep something > blah.txt , inadvertidamente cat blah.txt | grep something > blah.txt en blanco el archivo. Hay un pequeño comando de utilidad llamado sponge que puedes instalar (haces cat blah.txt | grep something | sponge blah.txt y almacena el contenido del archivo, luego lo escribe en el archivo). Es similar a un archivo temporal, pero no tiene que hacer eso explícitamente. pero diría que es un requisito "peor" que, por ejemplo, Perl.

Puede haber una manera de hacerlo a través de awk, o similar, pero si tiene que usar shell-script, creo que un archivo temporal es, de lejos, el más fácil (¿solo?).


El truco a continuación fue una respuesta rápida que funcionó y recibió muchos votos ascendentes. Luego, a medida que la pregunta se hizo más popular y pasó más tiempo, las personas indignadas empezaron a informar que funcionaba pero que cosas extrañas podían suceder, o que simplemente no funcionaba en absoluto, por lo que se vino abajo furiosamente por un tiempo. Qué divertido.

La solución explota la implementación exacta de los descriptores de archivos en su sistema y, debido a que la implementación varía significativamente entre nixes, su éxito depende completamente del sistema, definitivamente no es portátil, y no debe confiarse en él para algo incluso vagamente importante.

Ahora, con todo eso fuera del camino, la respuesta fue:

La creación de otro descriptor de archivo para el archivo ( exec 3<> yourfile ) desde allí escribiendo ( >&3 ) parece superar la lectura / escritura en el mismo dilema de archivo. Funciona para mí en 600K archivos con awk. Sin embargo, falla el intento de usar el mismo truco con ''gato''.

Pasar el preámbulo como una variable a awk ( -v TEXT="$text" ) supera el problema de citas literales que evita hacer este truco con ''sed''.

#!/bin/bash text="Hello world What''s up?" exec 3<> yourfile && awk -v TEXT="$text" ''BEGIN {print TEXT}{print}'' yourfile >&3


El que yo uso. Este te permite especificar el orden, los caracteres extra, etc. de la manera que te gusta:

echo -e "TEXTFIRSt/n$(< header)/n$(< my.txt)" > my.txt

PD: solo no funciona si los archivos contienen texto con barra diagonal inversa, porque se interpreta como caracteres de escape


En mi humilde opinión, no hay una solución de shell (y nunca será una) que funcione de manera consistente y confiable, independientemente del tamaño de los dos archivos myheader y myfile . La razón es que si quieres hacer eso sin recurrir a un archivo temporal (y sin dejar que el shell vuelva a aparecer silenciosamente en un archivo temporal, por ejemplo, a través de construcciones como exec 3<>myfile , piping to tee , etc.

La solución "real" que está buscando tiene que juguetear con el sistema de archivos, por lo que no está disponible en el espacio de usuario y depende de la plataforma: usted está pidiendo modificar el puntero del sistema de archivos en uso por myfile al valor actual del sistema de archivos puntero para myheader y reemplace en el sistema de archivos el EOF de myheader con un enlace encadenado a la dirección actual del sistema de archivos apuntada por myfile . Esto no es trivial y obviamente no puede ser hecho por un no superusuario, y probablemente tampoco por el superusuario ... Juega con inodos, etc.

Sin embargo, puedes más o menos simular esto usando dispositivos de bucle. Ver por ejemplo este hilo SO .


En su mayoría para divertirse / jugar al golf, pero

ex -c ''0r myheader|x'' myfile

hará el truco, y no hay oleoductos o redirecciones. Por supuesto, vi / ex no es realmente para uso no interactivo, por lo que vi parpadeará brevemente.


Esto es lo que descubrí:

echo -e "header /n$(cat file)" >file



John Mee: su método no está garantizado para funcionar, y probablemente fallará si antepone más de 4096 bytes de material (al menos eso es lo que sucede con gnu awk, pero supongo que otras implementaciones tendrán restricciones similares). No solo fallará en ese caso, sino que ingresará en un bucle sin fin donde leerá su propia salida, haciendo que el archivo crezca hasta que se llene todo el espacio disponible.

Pruébalo por ti mismo:

exec 3<>myfile && awk ''BEGIN{for(i=1;i<=1100;i++)print i}{print}'' myfile >&3

(advertencia: matarlo después de un tiempo o llenará el sistema de archivos)

Además, es muy peligroso editar archivos de esa forma, y ​​es un consejo muy malo, ya que si algo sucede mientras el archivo está siendo editado (bloqueo, disco lleno) casi se garantiza que el archivo quedará en un estado incoherente.


Me gusta el enfoque ed de @ fluffle lo mejor. Después de todo, los conmutadores de línea de comando de cualquier herramienta frente a los comandos de editor con guiones son esencialmente lo mismo aquí; no ver una solución de editor guionizada "limpieza" siendo menor o lo que sea.

Este es mi documento único adjunto a .git/hooks/prepare-commit-msg para .gitmessage archivo .gitmessage en repo para confirmar los mensajes:

echo -e "1r $PWD/.gitmessage/n./nw" | ed -s "$1"

Ejemplo .gitmessage :

# Commit message formatting samples: # runlevels: boot +consolekit -zfs-fuse #

Estoy haciendo 1r lugar de 0r , porque eso dejará la línea vacía lista para escribir en la parte superior del archivo de la plantilla original. No coloque una línea vacía en la parte superior de su .gitmessage , entonces, terminará con dos líneas vacías. -s suprime la salida de información de diagnóstico de ed.

En relación con pasar por esto, discovered que para vim-buffs también es bueno tener:

[core] editor = vim -c '':normal gg''


No es posible sin un archivo temporal, pero aquí va un oneliner

{ echo foo; cat oldfile; } > newfile && mv newfile oldfile

Puede usar otras herramientas como ed o perl para hacerlo sin archivos temporales.


Puede usar la línea de comando perl:

perl -i -0777 -pe ''s/^/my_header/'' tmp

Donde -i creará un reemplazo en línea del archivo y -0777 sorberá todo el archivo y hará ^ coincidir solo con el comienzo. -pe imprimirá todas las líneas

O si my_header es un archivo:

perl -i -0777 -pe ''s/^/`cat my_header`/e'' tmp

Donde / e permitirá una evaluación de código en la sustitución.


Si estás creando scripts en BASH, en realidad, solo puedes emitir:

cat - yourfile /tmp/out && mv /tmp/out yourfile

Eso es en realidad en el ejemplo complejo que usted mismo publicó en su propia pregunta.


Si necesita esto en las computadoras que controla, instale el paquete "moreutils" y use "sponge". Entonces puedes hacer:

cat header myfile | sponge myfile


Si tiene un archivo grande (unos cientos de kilobytes en mi caso) y acceso a Python, esto es mucho más rápido que las soluciones de cat :

python -c ''f = "filename"; t = open(f).read(); open(f, "w").write("text to prepend " + t)''


Una solución con printf :

new_line=''the line you want to add'' target_file=''/file you/want to/write to'' printf "%s/n$(cat ${target_file})" "${new_line}" > "${target_file}"

También podrías hacer:

printf "${new_line}/n$(cat ${target_file})" > "${target_file}"

Pero en ese caso, debe asegurarse de que no haya ningún % ninguna parte, incluidos los contenidos del archivo de destino, ya que eso puede interpretarse y estropear sus resultados.


Una variante de la solución de cb0 para "ningún archivo temporal" para anteponer el texto fijo:

echo "text to prepend" | cat - file_to_be_modified | ( cat > file_to_be_modified )

De nuevo, esto depende de la ejecución del subcuadro: (...) para evitar que el gato se niegue a tener el mismo archivo para la entrada y la salida.

Nota: Me gustó esta solución. Sin embargo, en mi Mac, el archivo original está perdido (pensó que no debería, pero lo hace). Eso podría solucionarse escribiendo su solución como: echo "text to prepend" | cat - file_to_be_modified | cat> tmp_file; mv tmp_file file_to_be_modified


Usando un bash heredoc puede evitar la necesidad de un archivo tmp:

cat <<-EOF > myfile $(echo this is prepended) $(cat myfile) EOF

Esto funciona porque $ (cat myfile) se evalúa cuando se evalúa el script bash, antes de que se ejecute el gato con redirección.


Vale la pena señalar que a menudo es una buena idea generar de manera segura el archivo temporal utilizando una utilidad como mktemp , al menos si el script se ejecutará alguna vez con privilegios de administrador. Por ejemplo, podría hacer lo siguiente (nuevamente en bash):

(tmpfile=`mktemp` && { echo "prepended text" | cat - yourfile > $tmpfile && mv $tmpfile yourfile; } )


suponiendo que el archivo que desea editar es my.txt

$cat my.txt this is the regular file

Y el archivo que desea anteponer es el encabezado

$ cat header this is the header

Asegúrese de tener una línea en blanco final en el archivo de encabezado.
Ahora puedes precederlo con

$cat header <(cat my.txt) > my.txt

Terminas con

$ cat my.txt this is the header this is the regular file

Hasta donde sé, esto solo funciona en ''bash''.


variables, ftw?

NEWFILE=$(echo deb http://mirror.csesoc.unsw.edu.au/ubuntu/ $(lsb_release -cs) main universe restricted multiverse && cat /etc/apt/sources.list) echo "$NEWFILE" | sudo tee /etc/apt/sources.list



current=`cat my_file` && echo ''my_string'' > my_file && echo $current >> my_file

donde "my_file" es el archivo para anteponer "my_string" a.



sed -i -e "1s/^/new first line/n/" old_file.txt


sed -i -e ''1rmyheader'' -e ''1{h;d}'' -e ''2{x;G}'' myfile