リダイレクト、パイプ、関数なしでファイルにテキストを書き込むコマンドはありますか?

リダイレクト、パイプ、関数なしでファイルにテキストを書き込むコマンドはありますか?

パイプとリダイレクトはLinuxの最も強力な機能の2つであり、私はそれが好きです。

しかし、パイプ、リダイレクト、または関数を使用せずにファイルに固定テキストを書き込む必要がある状況に直面しました。

万が一に備えてBashを使用します。

まず:なぜですか?

より簡単な解決策がある場合は、その理由を説明します。

いくつかのメニュー項目を含む背景ヤード通知があります。一部のメニュー項目では、ファイルに固定テキストを書き込むように通知します。私が意味するものの例は次のとおりです。

yad --notification --command=quit --menu='Example!echo sample >text.txt'

問題は、yadがリダイレクトを許可しないため、実際にsample >text.txtリダイレクトの代わりに文字列を印刷することです。

同様に、パイプ記号(|)はyadの区切り文字ですが、それを変更するとyadはそれをリテラル文字として扱います。たとえば、

yad --notification --command=quit --separator='#' --menu='Example!echo sample | tee text.txt'

sample | tee text.txtこれは実際にパイプの代わりに文字列を印刷します。

yadが独自のスペースで実行され、関数を認識しないため、yadが呼び出す関数を作成することも意味がありません。

だから私の質問

echoしたがって、出力ファイルをリダイレクトするのではなく、パラメータとして使用するのとcat同じコマンドが必要です。printfそのコマンドを検索しましたが、見つかりませんでした。

もちろん、自分で作成してデフォルトのパスに入れることもできます。

FILENAME="${1}"
shift
printf '%s\n' "${*}" >"${FILENAME}"

それから

yad --notification --command=quit --menu='Example!myscript text.txt sample'

しかし、Linuxにまだこのような機能がない場合は、本当に驚くでしょう!

ありがとう

答え1

これは少しXYの問題しかし幸いなことに、実際の問題を説明してくれて意味のある答えを出すことができました。

もちろん、ファイルを開く環境に依存せずにファイルにテキストを書き込むコマンドがあります。たとえば、sh次のようにできます。パラメータ-cとを渡しますecho text >filename

この点に注意してくださいするの出力はshどこにもリダイレクトされないため、ここで「リダイレクトなし」の要件を満たしています。実行中のプログラムの内部にリダイレクトがありますが、sh大丈夫です。shこれはどのように機能するのかについての詳細です。

しかし、これは実際の問題を解決しますか?実際の問題は、ヤード操作でファイルにテキストを書き込むことです。この問題を解決するには、ヤードの運用が何であるかを知る必要があります。残念ながら、手動これは文書化されていません。それが言うすべて

menu:STRING

通知アイコンのポップアップメニューを設定します。STRING形になっていなければなりませんname1[!action1[!icon1]]|name2[!action2[!icon2]]...。名前が空の場合、メニューに区切り文字が追加されます。値区切り記号(例|:)はパラメータを使用して設定されます--separator。メニュー項目の区切り記号(たとえば!)は、パラメータを使用して設定されます--item-separator

操作は文字列ですが、Unixコマンドはコマンド名や引数などの文字列のリストです。文字列をコマンド名とその引数に変換するには、次のようないくつかの方法があります。

  • 文字列をコマンド名として処理し、引数なしで呼び出します。プログラムを実行する代わりにecho foo印刷するので、yadはそのようなことをしません。fooecho foo
  • 文字列をシェルに渡します。echo >filename印刷する>filenameのは書くものではないので、filenameこれはyadがすることではありません。
  • いくつかのカスタム文字列分割。この時点で、これはおおよそyadが行うことですが、正確に実行する方法によって問題の解決策が異なる場合があります。

見ているソースコード、ジョブが次に渡されます。popup_menu_item_activate_cbGlib関数を呼び出します。g_spawn_command_line_async。この関数は、次のように指定された文字列を分割します。g_shell_parse_argv次のような動作がありますが、これは私たちが望むものとはほとんど異なりますが、解決できます。

シェルとほぼ同じ方法でコマンドラインを引数ベクトルに解析しますが、シェルが実行する多くの拡張はありません(変数拡張、ワイルドカード、演算子、ファイル名拡張などはサポートされていません)。入力にサポートされていないシェル拡張が含まれていない限り、結果はUNIX98 / bin / shで得られた結果と同じに定義されます。入力にこれらの拡張が含まれている場合は、文字通り渡されます。

sh -c 'したがって、プレフィックスを追加して'。で終わると、シェルコマンドを実行できます。シェルコマンドで一重引用符を使用する必要がある場合は、作成してください'\''。または、前に を付けて で終わり、sh -c "コマンドに表示される文字の前にバックスラッシュを追加してシェルコマンドを実行することもできます。アクション自体がyadを呼び出すシェルスクリプトで参照されるため、ネストされた参照に注意してください。""$\`

yad --notification \
  --menu='Simple example!sh -c "echo sample text >text.txt"' \
  --menu='Single-double-single quotes!sh -c "echo '\''Here you can put everything except single quotes literally: two  spaces, a $dollar and a single'\''\'\'''\''quote.'\'' >text.txt"' \
  --menu="Double-single-double quotes!sh -c 'echo \"Here punctuation is a bit tricky: two  spaces, a \\\$dollar and a single'\\''quote.\"' >text.txt'"

答え2

シェルの機能を使用するには、シェルを実行してください。

yad --notification --command=quit --menu='Example!sh -c "echo sample >text.txt"'

答え3

簡単なカスタムスクリプトは次のとおりですprintto.py

#!/usr/bin/python

import sys

if len(sys.argv) == 3:
    f = open(sys.argv[1], "w")
    f.write(sys.argv[2])
    f.close()
else :
    print("usage: printto.py file message")
    sys.exit(1)

答え4

「yad」が括弧内のサブプロセス/サブシェルとして実行されるのか、サブプロセスでリダイレクトが可能かを知りたいです。

 ( yad BLAH BLAH BLAH ) > output.txt

または

( yad BLAH BLAH BLAH ) >& output.txt

関連情報