web-dev-qa-db-ja.com

Bashはエコーなしでファイルに書き込みますか?

演習として、エコーなしで文字列をファイルにリダイレクトする方法はありますか?現在使用しています

echo "Hello world" > test.txt

catprintfについて知っています。私は次のようなものを考えていました

> test.txt <<<"Hello world"

もちろんこれは機能しませんが、おそらく同様のコマンドですか?

38
anon

これを行うには、「cat」とヒアドキュメントを使用します。

cat <<EOF > test.txt
some text
EOF

これを行う理由の1つは、psの出力にパスワードが表示される可能性を回避するためです。ただし、bashおよび最新のシェルでは、「echo」は組み込みコマンドであり、ps出力には表示されないため、このようなものを使用しても安全です(もちろん、パスワードをファイルに保存する際の問題は無視します)。

echo "$password" > test.txt
56
Eric

「>」を送信できないという問題が発生し、エコーになりました!

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

Bashでこれを行う方法は

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

これは、zshとbashの興味深い違いの1つです。チェーンなしの> または >>、zshは標準入力に接続するのが適切ですが、bashには接続しません。それが実に便利だろう-それが標準だけだったなら。これを使用して、ssh経由でSSHキーをリモート_に送信および追加しようとしましたauthorized_keysファイルですが、リモートホストはもちろんbashであり、静かに何もしませんでした。

そして、だからこそcatを使うべきです。

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

それをするだろう

3
David Burke

おそらくあなたが気にかけないことを議論する方法は多すぎます。もちろんハックできます-strace bash、またはgdbでBashを実行するあらゆる種類の黒魔術を実行します。

実際には、まったく異なる2つの例があります。 <<<'string'はすでに文字列をファイルに書き込んでいます。 printfecho、およびcat以外のものが受け入れられる場合、他の多くのコマンドを使用してcatのように動作できます(sed、awk、teeなど)。

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

または、Bashのコンパイル方法に応じて、地獄。

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

純粋なbashで、ハッキングやロード可能ファイルを使用せずに、bash文字列とリダイレクトのみを使用する場合、それは不可能です。ただし、ksh93では可能です。

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

現在開いているファイル記述子を接続するものがないため、リダイレクトのみが機能しません。だから、このような方法はありません。

私はbash純粋主義者のための解決策を持っています。

関数 'define'は、変数に複数行の値を割り当てるのに役立ちます。これは、1つの定位置パラメーター、つまり値を割り当てる変数名を取ります。

ヒアドキュメントでは、オプションでパラメーター展開もあります!

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

ラッキーに!

1
Ivan Gut

それを行うには複数の方法があります。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

これは、表示されるはずの出力です。

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

ファイルには次のものが含まれている必要があります。

$ 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