web-dev-qa-db-fra.com

Bash écrire dans un fichier sans écho?

En exercice, existe-t-il une méthode pour rediriger une chaîne vers un fichier sans écho? J'utilise actuellement

echo "Hello world" > test.txt

Je connais cat et printf. Je pensais quelque chose comme

> test.txt <<<"Hello world"

Bien sûr, cela ne fonctionne pas, mais peut-être une commande similaire?

38
anon

Vous pouvez le faire avec "cat" et un document ici.

cat <<EOF > test.txt
some text
EOF

Une des raisons est d'éviter toute possibilité qu'un mot de passe ne soit visible dans la sortie de ps. Cependant, dans les shells bash et la plupart des shells modernes, "echo" est une commande intégrée qui n'apparaîtra pas dans la sortie ps. Il est donc prudent d'utiliser une méthode semblable (ignorer les problèmes de stockage des mots de passe dans les fichiers, bien sûr):

echo "$password" > test.txt
56
Eric

J'ai eu le problème de ne pas pouvoir envoyer ">" et j'ai fini avec écho!

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

La façon de faire ceci à bash est

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

C’est l’une des différences intéressantes entre zsh et bash: étant donné un _ déchaîné > ou >>, zsh a le bon sens de le connecter à stdin, contrairement à bash. Ce serait carrément utile - si ce n'était que la norme. J'ai essayé d'utiliser ceci pour envoyer et ajouter ma clé ssh sur ssh à une télécommande authorized_keys fichier, mais l'hôte distant était bash, bien sûr, et n'a rien fait discrètement.

Et c'est pourquoi vous devriez simplement utiliser cat.

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

le ferait

3
David Burke

Il existe bien trop de moyens de discuter dont vous ne vous souciez probablement pas. Vous pouvez bien sûr bidouiller - strace bash, ou faire toutes sortes de magie noire en exécutant Bash dans gdb.

Vous avez en fait deux exemples complètement différents. <<<'string' écrit déjà une chaîne dans un fichier. Si quelque chose est acceptable autre que printf, echo et cat, vous pouvez utiliser beaucoup d'autres commandes pour vous comporter comme un chat (sed, awk, tee, etc.).

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

Ou diable, selon la manière dont vous avez compilé Bash.

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

Si vous souhaitez utiliser uniquement des chaînes bash et une redirection, en bash pur, sans piratage ni chargement, ce n'est pas possible. En ksh93 cependant, c'est possible.

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

Seule la redirection ne fonctionnera pas, car rien ne permet de connecter les descripteurs de fichiers maintenant ouverts. Donc non, il n'y a pas moyen comme ça.

2

J'ai une solution pour les puristes bash.

La fonction 'define' nous aide à affecter une valeur multiligne à une variable. Celui-ci prend un paramètre de position: le nom de la variable pour assigner la valeur.

Dans l’heredoc, il existe éventuellement des extensions de paramètres!

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

Avoir de la chance!

1
Ivan Gut

Il y a plusieurs façons de le faire, exécutons ce script appelé 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

Voici le résultat que vous devriez voir:

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

Et les fichiers doivent contenir ceux-ci:

$ 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