it-swarm.com.de

Bash ohne Echo in Datei schreiben?

Gibt es als Übung eine Methode, um einen String ohne Echo in eine Datei umzuleiten? Zur Zeit benutze ich

echo "Hello world" > test.txt

Ich kenne cat und printf. Ich dachte so etwas wie

> test.txt <<<"Hello world"

Natürlich funktioniert das nicht, aber vielleicht ein ähnlicher Befehl?

38
anon

Sie können dies mit "cat" und einem Here-Dokument tun.

cat <<EOF > test.txt
some text
EOF

Ein Grund dafür wäre, die Möglichkeit zu vermeiden, dass ein Passwort in der Ausgabe von ps sichtbar wird. In bash und den meisten modernen Shells ist "echo" jedoch ein integrierter Befehl und wird in der ps-Ausgabe nicht angezeigt. Daher ist die Verwendung dieser Funktion sicher (natürlich ohne Berücksichtigung von Problemen beim Speichern von Passwörtern in Dateien):

echo "$password" > test.txt
56
Eric

Ich hatte das Problem, dass ich kein ">" senden konnte und es kam zum Echo!

echo "Hello world" | dd of=test.txt
15
guest

Der Weg, dies in bash zu tun, ist

zsh <<< '> test <<< "Hello World!"'

Dies ist einer der interessanten Unterschiede zwischen zsh und bash: Wenn ein > Oder >> Ungekettet ist, hat zsh den guten Sinn, ihn mit stdin zu verbinden, während bash dies nicht tut. Es wäre ausgesprochen nützlich - wenn es nur Standard wäre. Ich habe versucht, damit meinen SSH-Schlüssel über SSH an eine entfernte authorized_keys - Datei anzuhängen, aber der entfernte Host war natürlich heftig und tat im Stillen nichts.

Und deshalb solltest du nur cat verwenden.

3
perickso
awk ' BEGIN { print "Hello, world" } ' > test.txt

würde es tun

3
David Burke

Es gibt viel zu viele Möglichkeiten zu diskutieren, um die Sie sich wahrscheinlich nicht kümmern. Sie können natürlich hacken - Bash stracen oder alle Arten von schwarzer Magie ausführen, indem Sie Bash in gdb ausführen.

Sie haben dort tatsächlich zwei völlig unterschiedliche Beispiele. <<<'string' schreibt bereits einen String in eine Datei. Wenn etwas anderes akzeptabel ist als printf, echo und cat, können Sie viele andere Befehle verwenden, um sich wie cat zu verhalten (sed, awk, tee, etc).

$ cp /dev/stdin ./tmpfooblah <<<'hello world'; cat tmpfooblah
hello world

Oder verdammt, je nachdem, wie du Bash kompiliert hast.

$ enable -f /usr/lib/bash/print print; print 'hello world' >tmpfile

Wenn Sie nur Bash-Strings und Umleitung verwenden möchten, ist dies in reiner Bash, ohne Hacken und ohne ladbare Dateien, nicht möglich. In ksh93 ist dies jedoch möglich.

 $ rm tmpfooblah; <<<'hello world' >tmpfooblah <##@(&!()); cat tmpfooblah
 hello world
3
ormaaj

Nur die Umleitung funktioniert nicht, da die jetzt geöffneten Dateideskriptoren nicht verbunden werden können. Also nein, es gibt keinen Weg wie diesen.

Ich habe eine Lösung für Bash-Puristen.

Die Funktion 'define' hilft uns, einer Variablen einen mehrzeiligen Wert zuzuweisen. Dieser akzeptiert einen Positionsparameter: den Variablennamen, um den Wert zuzuweisen.

Optional gibt es im heredoc auch Parametererweiterungen!

#!/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" 

Sei glücklich!

1
Ivan Gut

Es gibt mehrere Möglichkeiten, dies zu tun. Führen Sie das Skript mit dem Namen exercise.sh Aus.

#!/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

Dies ist die Ausgabe, die Sie sehen sollten:

$ bash exercise.sh
Here is another here-string I can see and write to file

Und Dateien sollten diese enthalten:

$ 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
0
sdkks