RAMに一時ファイルを作成する方法は?


29

出力をにパイプするスクリプトがあります|tee scriptnameYYMMDD.txt。出力が生成されるforループの各サイクルの後tac scriptnameYYYYMMDD.txt > /var/www/html/logs/scriptname.txt、ログの出力がブラウザーウィンドウに表示され、最新の行が一番上に表示されるように、ファイルの内容を逆にします。

これを並行して行うスクリプトがいくつかあります。ディスクアクティビティを最小化しようとしているので|tee scriptnameYYYYMMDD.txt、RAMdiskへの出力が最適です。フォルダーにmktempファイルを作成しますが、/tmpそれはオフディスクではないようです。


ramfsまたはtmpfsである必要があります(2番目の方が優れています)。そのようなfsがすでにシステムにマウントされているかどうかを確認します。そうであれば、使用できます。いいえの場合は、マウントする必要があります。
ペテルは、モニカを

私は更新したいfstabマウントするために、tmpfs上で/tmp、その後、マシンを再起動します。
カスペルド

1
全体を実行するのではなくtail、ファイルを段階的に実行する(または要求に応じてCGIを介して開始する)ことを検討してくださいtac
mikeserv

これはテストで機能しているようです(フォーマットの縮小については申し訳ありません): TEMPPATH="/ramdisk" LOGPATH="/var/www/html/log" ... echo <various calls to echo> | tee -a $TEMPPATH/moveKRT$(date '+%Y%m%d').txt ... forループの終了時に cp $TEMPPATH/moveKRT$(date '+%Y%m%d').txt $LOGPATH/moveKRT$(date '+%Y%m%d').txt tac $TEMPPATH/moveKRT$(date '+%Y%m%d').txt > $LOGPATH/moveKRT.txt 、23:59:59.999から00:00への変更というごくわずかな可能性を認識しています。 00は一部のファイルに影響を与える可能性がありますが、可能性は許容されます。
user208145

これに関する進捗状況の更新:/ ramdiskに1 GBのtmpfsボリュームがマウントされています。FTP経由でユーザーのホームフォルダーにファイルが入っています。それらはサブフォルダー/ ramdisk / queues / xyz /に移動して処理され、その後削除されます。起動時に、必要なディレクトリ構造を/ ramdiskの下に再作成するスクリプトがあります。これにより、着信ファイルのディスクアクティビティが最小限になります。これまでのところ、これらのスクリプトのディスクI / Oを削減する唯一の方法は、起動時に作成されたtmpfsにユーザーフォルダーを作成し、FTPを介してそれらのユーザーフォルダーにファイルを取り込むことです。皆さんありがとう。
user208145

回答:


22

tmpfsパーティションをマウントして、そこにファイルを書き込むことができます:

mount -t tmpfs -o size=500m tmpfs /mountpoint

現在、このパーティションは500 MBに制限されています。一時ファイルが500 MBを超えると、エラーが発生します:no space left on device。ただし、システムのRAMの容量よりも大きな容量を指定する場合は問題ではありません。tmpfsスワップ空間も使用するため、の代わりにシステムを強制的にクラッシュさせることはできませんramfs

ファイルを/mountpoint次の場所に書き込むことができます。

command | tee /mountpoint/scriptnameYYYYMMDD.txt

3
size=[num]%また、tmpfsは使用可能なメモリの割合に制限できます。通常、コマンドが常に同じ(実/仮想)マシンを対象とするわけではない場合、この方法は簡単です。また、便利なのは、tmpfsがコンテンツw /をドロップしないこと-o remount,size=newsizeです。
mikeserv

1
私たちはrootによって実行されると仮定する理由がないbashスクリプトの周りの質問公転、以来、あなたは1つが周りを取得することができるかどうかを指定することができmount、非rootユーザーが使用することを許可していません-t-o?つまりtmpfs、適切なファイルシステムがシステム上にまだ存在しない場合に、ディスク操作を保存するために使用する(または他の方法でRAM を使用する)スクリプトをどのように構築できますか?
ジョナサンY.

良い答えではありません。ルートでない場合は失敗します。
アレックス

11

Ubuntuでこれを試してください:

ramtmp="$(mktemp -p /dev/shm/)"
tac scriptnameYYYYMMDD.txt > "$ramtmp"

3
への書き込みはどれくらい安定してい/run/shm/ますか?chmod必要に応じて一時ファイルに変更を適用できますか?フォルダーのモードビットが/tmpフォルダーと同じであることに気付きました。ありがとう。
user208145

1
他のディレクトリについては、で生成された/run/shm(へのシンボリックリンク/dev/shm)ファイルにmktemp-rw-------(600)のデフォルトのパーミッションもあり、必要に応じてで変更できますsudo chmod
KrisWebDev

9

以下の回答は、以前の回答とこの質問の情報をここで調査することで発見されたものであり、それらがなければ見つかりませんでした。それらへの称賛。

私のlinuxmintシステム(そして、ほとんどのUbuntuベースのシステムと、おそらくDebianベースのシステムも想定しています)には、ユーザーが所有するtmpfsが自動的にマウントされています /run/user/1000/

df -Tチェックに使用します。

11:41:11 jesse @ Limbo:〜$ df -T
ファイルシステムタイプ使用済み1Kブロック使用可能使用率%マウント済み
udev devtmpfs 15904812 4 15904808 1%/ dev
tmpfs tmpfs 3184120 1700 3182420 1%/実行
/ dev / sdb2 ext4 14248880 11464788 2037240 85%/
なしtmpfs 4 0 4 0%/ sys / fs / cgroup
なしtmpfs 5120 0 5120 0%/ run / lock
なしtmpfs 15920584 848 15919736 1%/ run / shm
なしtmpfs 102400 12 102388 1%/ run / user
/ dev / sdb3 ext4 100861352 90755700 4959136 95%/ mnt / data

/run/user/には、システム上の各通常ユーザー用のディレクトリがあります

12:07:35 jesse@Limbo:~$ ls -l /run/user
total 0
drwx------ 2 root  root   40 Aug  7 09:50 0
drwx------ 8 jesse jesse 180 Aug  7 11:38 1000

これらのディレクトリは、それぞれのユーザーのIDに基づいて名前が付けられます。このコマンドの詳細については、id -usee man idでユーザーIDを取得できます。

12:07:43 jesse@Limbo:~$ ls -l /run/user/$(id -u)
total 0
drwx------ 2 jesse jesse  60 Aug  7 09:50 dconf
dr-x------ 2 jesse jesse   0 Aug  7 09:50 gvfs
drwx------ 2 jesse jesse  80 Aug  7 09:50 pulse
lrwxrwxrwx 1 root  root   17 Aug  7 09:50 X11-display -> /tmp/.X11-unix/X0

このオプションを指定mktempしたコマンドを使用して--tmpdir、このtempfilesystemに一時ファイルとディレクトリを作成し、RAMに一時ファイルを作成できます。

ここで与えられたアドバイスに従って、まず一時ディレクトリを作成してから、その中に一時ファイルを作成します。

mydir=$(mktemp -dt "$(basename $0).XXXXXXXX" --tmpdir=/run/user/$(id -u))

一時ディレクトリを作成するに/run/user/1000/bash.w42BYxbG/

myfile=$(mktemp -t "$(basename $0).XXXXXXXX" --tmpdir=$mydir)

一時ファイルを作成します。

これにより、これらのファイルを簡単にクリーンアップできますrm -r $mydir

デフォルトでは、これらのファイルはすべて所有されており、作成したユーザーのみが読み取り可能です。

注:$(basename $0)コマンドの一部は、mktempを実行したスクリプト/プロセスの名前を抽出します。私は、スクリプトを使用している場合 /home/jesse/scripts/myScript.sh、次に$(basename $0)返します myScript.sh。このスクリプトによって実行されたとき。したがって、上記のコマンドはそれぞれを作成/run/user/1000/myScript.sh.w42BYxbG//run/user/1000/myScript.sh.w42BYxbG/myScript.sh.BCzSmq06ます。


/run/user/1000systemdを使用する各Linuxで利用できるため、Debianベースのシステムだけでなく、他のほとんどのLinuxディストリビューションでも利用できます。そうでない場合は、代わりに/ tmpを使用する必要があります。各ユーザーの正しいディレクトリを既に保持している変数$ XDG_RUNTIME_DIRを使用して、コマンドを簡素化できます。詳細については、たとえば次の回答を確認してください。unix.stackexchange.com
アレックス

1
mktempではなくmkstempを使用してください!! 理由:linux.die.net/man/3/mktemp:バグセクションの「... mktemp()の使用はすべてセキュリティリスクです。mkstemp(3)によって競合が回避されます。」
アレックス

0

私の理解では、目的は次のとおりです。(1)ないブラウザに提供するために、ディスクへの逆ファイルを保存する(注:これはすべてのように、など、他の回答既に詳細tmpfsのかもしれません)。ただし、(2)元の出力を使用して、最初のtmpファイルをディスクに書き込まないでください。それでも、(3)まだ元の出力を標準出力に表示します。

その場合、bashプロセス置換(つまり、基本的に名前付きパイプ)を使用して、以下がニーズを満たす可能性があります。

command | tee >( tac > /var/www/html/logs/scriptname.txt )

これは出力を標準出力に継続的に印刷し、コマンドが終了するとき(ループが終了するとき)、その出力を反転して出力ファイルに書き込むことに注意してください。次の図を参照してください。1秒に1行印刷さ/tmp/foo.txtれ、終了後、ファイルには反転行が含まれます。

i=0
while [ $i -lt 10 ]; do
    ((i = i+1))
    echo "==$i== $(date)"
    sleep 1
done | tee >( tac >> /tmp/foo.txt ) 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.