script - Bash escribir en el archivo sin eco?
scripts bash ejemplos (8)
Como ejercicio, ¿existe un método para redirigir una cadena a un archivo sin eco? Actualmente estoy usando
echo "Hello world" > test.txt
Sé de cat
y printf
. Estaba pensando algo como
> test.txt <<<"Hello world"
Por supuesto, esto no funciona, pero tal vez un comando similar?
Hay demasiadas maneras de discutir que probablemente no te importa. Por supuesto, puedes hackear - strace bash, o hacer todo tipo de magia negra ejecutando Bash en gdb.
En realidad tienes dos ejemplos completamente diferentes allí. <<<''string''
ya está escribiendo una cadena en un archivo. Si cualquier otra cosa es aceptable que no sea printf
, echo
y cat
, puede usar muchos otros comandos para comportarse como cat (sed, awk, tee, etc.).
$ cp /dev/stdin ./tmpfooblah <<<''hello world''; cat tmpfooblah
hello world
O infierno, dependiendo de cómo hayas compilado Bash.
$ enable -f /usr/lib/bash/print print; print ''hello world'' >tmpfile
Si desea utilizar solo cadenas y redireccionamientos de bash, en bash puro, sin pirateo, y sin adorables, no es posible. En ksh93 sin embargo, es posible.
$ rm tmpfooblah; <<<''hello world'' >tmpfooblah <##@(&!()); cat tmpfooblah
hello world
Hay varias formas de hacerlo, ejecutemos este script llamado exercise.sh
#!/usr/bin/env bash
> file1.txt cat <<< "This is a here-string with random value $RANDOM"
# Or if you prefer to see what is happening and write to file as well
tee file2.txt <<< "Here is another here-string I can see and write to file"
# if you want to work multiline easily
cat <<EOF > file3.txt
You don''t need to escape any quotes here, $ marks start of variables, unless escaped.
This is random value from variable $RANDOM
This is literal /$RANDOM
EOF
# Let''s say you have a variable with multiline text and you want to manipulate it
a="
1
2
3
33
"
# Assume I want to have lines containing "3". Instead of grep it can even be another script
a=$(echo "$a" | grep 3)
# Then you want to write this to a file, although here-string is fine,
# if you don''t need single-liner command, prefer heredoc
# Herestring. (If it''s single liner, variable needs to be quoted to preserve newlines)
> file4.txt cat <<< "$a"
# Heredoc
cat <<EOF > file5.txt
$a
EOF
Esta es la salida que debería ver:
$ bash exercise.sh
Here is another here-string I can see and write to file
Y los archivos deben contener estos:
$ ls
exercise.sh file1.txt file2.txt file3.txt file4.txt file5.txt
$ cat file1.txt
This is a here-string with random value 20914
$ cat file2.txt
Here is another here-string I can see and write to file
$ cat file3.txt
You don''t need to escape any quotes here, $ marks start of variables, unless escaped.
This is random value from variable 15899
This is literal $RANDOM
$ cat file4.txt
3
33
$ cat file5.txt
3
33
La forma de hacer esto en bash es
zsh <<< ''> test <<< "Hello World!"''
Esta es una de las diferencias interesantes entre zsh y bash: dado un desencadenado >
o >>
, zsh tiene el buen sentido de conectarlo a stdin, mientras que bash no. Sería francamente útil, si fuera solo estándar. Intenté usar esto para enviar y adjuntar mi clave ssh a ssh a un archivo authorized_keys
, pero el host remoto era bash, por supuesto, y silenciosamente no hizo nada.
Y es por eso que solo debes usar cat
.
Puedes hacer esto con "cat" y un documento aquí.
cat <<EOF > test.txt
some text
EOF
Una razón para hacer esto sería evitar cualquier posibilidad de que una contraseña sea visible en la salida de ps. Sin embargo, en bash y en la mayoría de los shells modernos, "echo" es un comando incorporado y no se mostrará en la salida ps, por lo que usar algo como esto es seguro (ignorar cualquier problema con el almacenamiento de contraseñas en archivos, por supuesto):
echo "$password" > test.txt
Solo la redirección no funcionará, ya que no hay nada para conectar los descriptores de archivos ahora abiertos. Así que no, no hay manera como esta.
Tengo una solución para los puristas del bash.
La función ''definir'' nos ayuda a asignar un valor multilínea a una variable. Éste toma un parámetro posicional: el nombre de la variable para asignar el valor.
En el heredoc, opcionalmente también hay expansiones de parámetros!
#!/bin/bash
define ()
{
IFS=$''/n'' read -r -d '''' $1
}
BUCH="Matthäus 1"
define TEXT<<EOT
Aus dem Buch: ${BUCH}
1 Buch des Geschlechts Jesu Christi, des Sohnes Davids, des Sohnes Abrahams.
2 Abraham zeugte Isaak; Isaak aber zeugte Jakob, Jakob aber zeugte Juda und seine Brüder;
3 Juda aber zeugte Phares und Zara von der Thamar; Phares aber zeugte Esrom, Esrom aber zeugte Aram,
4 Aram aber zeugte Aminadab, Aminadab aber zeugte Nahasson, Nahasson aber zeugte Salmon,
5 Salmon aber zeugte Boas von der Rahab; Boas aber zeugte Obed von der Ruth; Obed aber zeugte Isai,
6 Isai aber zeugte David, den König. David aber zeugte Salomon von der, die Urias Weib gewesen;
EOT
define TEXTNOEXPAND<<"EOT" # or define TEXTNOEXPAND<<''EOT''
Aus dem Buch: ${BUCH}
1 Buch des Geschlechts Jesu Christi, des Sohnes Davids, des Sohnes Abrahams.
2 Abraham zeugte Isaak; Isaak aber zeugte Jakob, Jakob aber zeugte Juda und seine Brüder;
3 Juda aber zeugte Phares und Zara von der Thamar; Phares aber zeugte Esrom, Esrom aber zeugte Aram,
4 Aram aber zeugte Aminadab, Aminadab aber zeugte Nahasson, Nahasson aber zeugte Salmon,
5 Salmon aber zeugte Boas von der Rahab; Boas aber zeugte Obed von der Ruth; Obed aber zeugte Isai,
6 Isai aber zeugte David, den König. David aber zeugte Salomon von der, die Urias Weib gewesen;
EOT
OUTFILE="/tmp/matthäus_eins"
# Create file
>"$OUTFILE"
# Write contents
{
printf "%s/n" "$TEXT"
printf "%s/n" "$TEXTNOEXPAND"
} >>"$OUTFILE"
¡Suerte!
Tuve el problema de no poder enviar ">" y terminé con eco!
echo "Hello world" | dd of=test.txt
awk '' BEGIN { print "Hello, world" } '' > test.txt
Lo haría