2017-12-10 5 views
2

を失敗した私はこのコードを持っている:``システム( 'opensslの...')の直後に実行する場合FileUtils.mv`は、ファイルに `この作成した

... 
system("openssl ... -in #{path.shellescape} -out #{tmpfile.shellescape} ...") 
FileUtils.mv(tmpfile, path) 
... 

pathtmpfile"temporary"で、"randomFile.mobileprovision"です。

コードはrandomFile.mobileprovisionで、一時ファイルに暗号化して元のファイルにコピーしてください。 FileUtils.mvが実行されると、両方のファイルが存在するはずです。

しかし、私はこのようなエラーが出る:

Errno::ENOENT: 
No such file or directory @ rb_file_s_rename - (temporary, randomFile.mobileprovision) 

奇妙に。

"デバッグ中"私はFileUtils.mvの前に "puts` ls`を置いた。突然それが働いた!
sleep(0.1)FileUtils.mv...の前に置くと同じです - それはではなく、はもう失敗します。
何が起こっているのですか?


これは(...私が想像できない)systemのいずれかは、それがあるべきほどの同期ではないことを信じるように私を導いたか、そのopensslファイルが実際にディスクに書き込まれる前に、実際に返されます。

は私が

system("openssl ...") 
puts Time.now.round(10).iso8601(9) 
puts `ls -l --time-style=full-iso #{Dir.mktmpdir}`  
FileUtils.mv(tmpfile, path) 

systemが返された後、これは現在の時刻を出力するコードを変更し確認するには、それは、ファイルが作成されたときかどうかを確認するためにディレクトリのリストを取得します。

マイ出力:

2017-12-10T05:40:58.309145900+01:00 

total 0 
-rw-rw-rw- 1 sujan sujan 20 2017-12-10 05:40:58.291071400 +0100 randomFile.mobileprovision 
-rw-rw-rw- 1 sujan sujan 65 2017-12-10 05:40:58.320572900 +0100 temporary 

のでsystemは0.30で行われます。
temporaryファイルは、.32!で作成されました!

これはどのように可能ですか?
これを修正または回避する方法を教えてください。


環境:ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux] WSL内のWindows 10上(Linux用のWindowsサブシステムは、Ubuntuのbashの)。

+0

'system()'の代わりにバックティックを使用するとどうなりますか?例えば'' output = 'openssl ...' '' –

+1

もう一つは試してみてください:システムに砲撃する代わりにOpenSSL gemを使う。 –

答えて

0

ないソリューションが、putsディレクトリのリストよりも優れ回避策:

だから、それはファイルが存在するまで、あなたがループする必要があるとしているように見えます:

until File.exist?("file1.csv") 
    sleep 1 
end 

出典:https://stackoverflow.com/a/4539472/252627

の代わりに0.1と使用します。上限は2です。秒はすべてMacシステム上にないことに依存します:

unless Helper.is_mac? 
    count = 0 
    # sleep until file exists or 20*0.1s (=2s) passed 
    until File.exist?(tmpfile) || count == 20 
     sleep(0.1) 
     count += 1 
    end 
    end 
関連する問題