Bashは標準出力をファイルにリダイレクトするのによく失敗します(catから)。

Bashは標準出力をファイルにリダイレクトするのによく失敗します(catから)。

私は通常、次のようにテキストファイルに追加しますcat

cat >> FILE

誤ってファイルを上書きするのを防ぐために、エイリアスを使用してください(単一ファイルを使用>)。

alias a='cat >>'

Enterは行を変更し、Ctrl+はDコマンドを終了します。私はホームフォルダに複数のテキストファイルを作成します。このファイルはすべて私が作成、所有、編集できます。

私はデスクトップLinuxシステム(Fedora 39)とTermux(Android)で入力を正常に受け入れているように見えますが、コマンドがファイルへのリダイレクトを停止したことがいくつかありました。何百行もありません。主に私が貼り付けたURLがありません。コマンドがしばらく実行された後にのみ発生するようです。

cat >>リダイレクトが機能しなくなる理由はありますか?たとえば、入力に特殊文字がある場合は違いがありますか?

修正する:個々のファイルのinode番号が変更され続けていることを確認しました($ ls -liまたは正確な時刻を確認するために使用$ stat -c '%w')。これが起こります。Syncthingは同期ファイルを再生成するように設計されているため。今後このソフトウェアをどのように使用するかを再評価する必要があります。最初は同期について言及していないので申し訳ありません。

私が自動化したコマンドでは、少なくともsed -i(ファイルをその場で編集して)inodeも置き換えました。

コマンドcat >> FILEも交換する必要があります(提供されたアドバイス、説明、回答を参照)。

ベストアンサー1

を実行すると、cat >> fileシェルはfd 1の子プロセスの現在の作業ディレクトリで開き、成功するとfileそのプロセスで実行されます。O_WRONLY|O_CREAT|O_APPENDcat

それ以外の場合、シェルはエラーメッセージを印刷して実行されませんcat

catまた、コマンドが見つからない場合は、エラーメッセージを印刷します。

catその後、ループから fd 0 を読み込み、読み取った内容を fd 1 に書き込みます。

同様に失敗すると、エラーメッセージが出力されます。

実行中のプロセスがcatシグナルによって終了または中断されると、シェルはそれをstderrにも報告する必要があります(例:ファイルサイズ制限を超えました。SIGXFSZ使用または殺す場合一時停止(tty入力)SIGTTINで一時停止した場合)。

fd 0 が tty デバイスで開いていて、その tty デバイスが同じ場合、シェルは通常実行する前にコマンドを読み込みます。catシェルは、独自の行を入力する前と同じ方法でttyを設定します。エディタ。行ルール。

icanon通常、これは線の規則がおおよその線エディタを実装するモードにあることを意味します。

その中で、行エディタは実際に特殊文字を認識する唯一のツールです。stty -aリストが提供されます。私:

$ stty -a
speed 38400 baud; rows 43; columns 159; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

icanon上記の内容を見ることができます。^C^\^?^U^D、 、^Q、 、^S、 、 、 、 、^Z^R^W、 文字は特別に処理されます。 //ターゲット(私の場合は有効)、/ターゲット(上記)はLinuxではサポートされていません。^V^O^C^Z^\isig^S^Qixondiscard^O

たとえば、foobar^Ubaz次のように入力するとfoobarただし、再入力すると、エコーからその内容が削除されることがわかります。

入力^C文字はcat途中で終了しますread

しかし、最近、ほとんどの端末エミュレータは貼り付けるとこれらの文字を削除します。。したがって、貼り付けるときにこれが発生するには、まだストリッピング操作を実行していない端末を使用するか、// kill...設定の一部を非制御文字に設定する必要があります。これは病理的です。 。weraseintr

行エディタには、編集できる行のサイズにも制限があります。 Linuxでは、IIRCの場合は4095バイトです。したがって、この値より大きい行を貼り付けると、4095番目のバイトを超える内容はすべて削除されます。

このicanonモードでは、ttyラインエディタが終了したときに返されます。これは、catまたはanyまたは文字を入力(onに変換)するときに発生します。read()^M^Jicrnl^Jeoleol2eof

ただし、とにかくcat正常に終了した場合、つまり^CSIGINT onまたはSIGQUIT onによって終了されない場合、または^\SIGTSTP onによって中断されず、^Zエラーが報告されない場合、端末は入力を読み取り、文書に書き込みます。 。

要約すると、あなたがしようとしていることは通常の状況では起こってはいけません。

  • 報告されたtty設定がstty -aすべてバグがありました。
  • または、貼り付けたデータには、ttyドライバの行エディタで解釈される制御文字が含まれており、何らかの理由で端末エディタからその文字を削除しません。

catシェルで報告されたエラーを特定できなかった、または思っていたものとは異なるディレクトリにファイルを作成したり、実行時にcat削除、置換、名前変更、または切り捨てなどの人間のエラーを無視しないでください。物事を同期あなたのコメントにusing)を言及しました。

そのエイリアスを使用して代わりにa='cat >>'入力すると、stdinと同じです。stdinから読み込み、代わりにstdinに出力を書き込みます。a some filea 'some file'cat >> some filecat file >> somecatfilesomesome file

このエイリアスに対する可能な改善点(GNU仮定tee)は次のとおりです。

a() {
  rlwrap -pblue -S 'add> ' tee --output-error=warn -a -- "$@" > /dev/null
}

元のttyドライバ(シェルとして使用している場合はすでに慣れている)rlwrapよりも高度なラインエディタを提供し、いくつかの入力を待っていることをより明確に知らせるプロンプトがあります。bash

そして、あなたはtee一度に複数のファイルに入力を書き込むことができます。

おすすめ記事