In terminal i could have used something like:
mv *.ext /some/output/dir/
I want to so the same in ruby. I can use system command for that under backticks (`) or using the system(), but how to achieve the same in ruby way?
I tried:
FileUtils.mv '*.sql', '/some/output/dir/'
This is not working as it looks specifically for a file name '*.sql'
You can do:
FileUtils.mv Dir.glob('*.sql'), '/some/output/dir/'
You need to use a Glob, as in:
Dir.glob('*.sql').each do|f|
# ... your logic here
end
or more succinct:
Dir.glob('*.sql').each {|f| FileUtils.mv(f, 'your/path/here')}
Check the official documentation on FileUtils#mv which has even an example with Glob.
Update: If you want to be sure you don't iterate (although I wouldn't worry about it that much) you can always execute what you consider to be optimized in shell, directly from ruby, e.g.:
`mv *.ext /some/output/dir/`
I will do using FileUtils::cp, as it copies a file content src to dest. If dest is a directory, copies src to dest/src. If src is a list of files, then dest must be a directory.
FileUtils.cp Dir['*.sql'], '/some/output/dir/'
I wouldn't use ::mv, as if file and dest exist on the different disk partition, the file is copied then the original file is removed.
But if you don't bother with the deletion of the original files, then go with ::mv.
Related
please take a look at the bin-win target in my repository here:
https://github.com/thinlizzy/bazelexample/blob/master/demo/BUILD#L28
it seems to be properly packing the executable inside a file named bin-win.tar.gz, but I still have some questions:
1- in my machine, the file is being generated at this directory:
C:\Users\John\AppData\Local\Temp_bazel_John\aS4O8v3V\execroot__main__\bazel-out\x64_windows-fastbuild\bin\demo
which makes finding the tar.gz file a cumbersome task.
The question is how can I make my bin-win target to move the file from there to a "better location"? (perhaps defined by an environment variable or a cmd line parameter/flag)
2- how can I include more files with my executable? My actual use case is I want to supply data files and some DLLs together with the executable. Should I use a filegroup() rule and refer its name in the "srcs" attribute as well?
2a- for the DLLs, is there a way to make a filegroup() rule to interpret environment variables? (e.g: the directories of the DLLs)
Thanks!
Look for the bazel-bin and bazel-genfiles directories in your workspace. These are actually junctions (directory symlinks) that Bazel updates after every build. If you bazel build //:demo, you can access its output as bazel-bin\demo.
(a) You can also set TMP and TEMP in your environment to point to e.g. c:\tmp. Bazel will pick those up instead of C:\Users\John\AppData\Local\Temp, so the full path for the output directory (that bazel-bin points to) will be c:\tmp\aS4O8v3V\execroot\__main__\bazel-out\x64_windows-fastbuild\bin.
(b) Or you can pass the --output_user_root startup flag, e.g. bazel--output_user_root=c:\tmp build //:demo. That will have the same effect as (a).
There's currently no way to get rid of the _bazel_John\aS4O8v3V\execroot part of the path.
Yes, I think you need to put those files in pkg_tar.srcs. Whether you use a filegroup() rule is irrelevant; filegroup just lets you group files together, so you can refer to the group by name, which is useful when you need to refer to the same files in multiple rules.
2.a. I don't think so.
I'm sending the file file.txt from my Rails controller using send_file, and then delete the folder containing it.
send_file("#{Rails.root}/public/folder/file.txt")
FileUtils.remove_dir "#{Rails.root}/public/folder", true
When I did this, file.txt was sent and deleted. However, folder was not deleted. But if I remove the send_file line, then folder will be deleted.
How do I make it delete folder?
EDIT: Interestingly, I found that inside folder there is a hidden file called .__afs2B0C, probably preventing the deletion. I have no idea how this file is created! The file stays for only around 15 minutes before disappearing.
EDIT2: I've tried inspecting the content of the temp file with vi, but it's unreadable gibberish. When I removed only the send_file line, the folder was correctly deleted. When I removed only the FileUtils.remove_dir line, the folder contains no temp file.
Are you sure the send_file is not still sending the file when you are removing the dir, it may be asynchronous if it uses X-SendFile? That would cause an error when trying to remove the dir.
So you should probably be queuing this delete action, or doing it with a sweeper later, rather than trying to do it straight after sending the file to streaming.
I'm not completely clear on which file you are sending, so it would be useful to include an actual example of file path, and file type, and how it is created in your question.
Possible help with debugging:
Log in and monitor the folder while you perform the following actions:
Write out a very large file (> 60MB say), and check there is no invisible file created during your file creation process - I'm not clear on which file you are actually sending
Set up a large file transfer on a slow connection, and watch for the creation and possibly growing of this file (it might be related to compressing the file served on the fly for example).
Given that sendfile may still be sending (for large files) via the web server (x-send-file is now default) when you try to delete, I'd try looking into delayed solutions.
Possible solutions:
Use send_data rather than send_file (if files are small)
Schedule the deletion of the folder for later with something like delayed_job
Set up a sweeper which removes the folders at the end of each day
Not sure why that hidden file is there, it could be an offshoot of X-send-file or even of wget (partial progress or something).
Ideally, you should use Tempfile to do things like this. The code is based of you're comment about what you are doing. Also, I am using two gems one for downloading and another for zipping.
This way, you don't need to make a folder at all, just a zip file directly. All the content files of the zip will be deleted on their own. After downloading the zip just delete it. Here also I should mention that you could run into a glitch somewhere, since the send_file will hand over the transfer to the webserver, and as such you don't the rails process to delete the file while it is still being served. So even with this, and it working well on localhost, I would strongly advise using a custom scheduled background garbage collector in production.
require 'open-uri'
require 'zip/zip'
zip_path = "#{Rails.root}/public/test.zip"
urls_to_fetch = ['abc.com', 'xyz.com']
Zip::ZipFile.open(zip_path, Zip::ZipFile::CREATE) do |zipfile|
urls_to_fetch.each_with_index do |url, index|
# intialize new temp file
file = Tempfile.new(index.to_s)
# fetch the file using open-uri or wget and save it as a tmpfile
open(url, 'rb') do |read_file|
file.write(read_file.read)
end
end
# add the temp file to the list of files to zip
zipfile.add(File.basename(file), file.path)
end
# send the zipfile for download
send_file zip_path
# delete the zipfile
FileUtils.rm zip_path
However, this should not be mandatory. If you are doing things without Tempfiles, please check the rights that the rails runner has on the target directory.
The FileUtils documentation has details regarding local security vulnerabilities when trying to delete files / folders.
See here... works for me
file = File.open(Rails.root.join('public', 'uploads', filename), "rb")
contents = file.read
file.close
File.delete(filepath) if File.exist?(filepath)
send_data(contents, :filename => filename)
maybe you could try this solution:
http://info.michael-simons.eu/2008/01/21/using-rubyzip-to-create-zip-files-on-the-fly/
it is so simple but dangerous. Use shell command to achieve it . Put it after send_file in Controller
system ("rm -rf public/folder")
What is the difference between:
include("./somepath/class.php");
and
include("somepath/class.php");
There shouldn't be any difference, directory wise, since the former assumes relative directory structure. The only potential pitfall could be if "somepath" were actually a command to be run - some users expect to type a command for a local script file and assume it should run, when you actually have to run "./somepath" to invoke it. This, of course, only pertains to commands not on your $PATH.
I don't see any difference. "." means current directory.
. refers to the current working directory.
Sometimes you want to specify explicitly that what you want is in the current working directory, and that it is not from something in your path variable for example.
For example in PHP "somepath/somefile" is appended after paths specified in include_dir (for example: /home/var/; /home/bin/ ....) directive.
The second variant is more specific it says: search in current directory!
Lets say, I setup my svn host, like: http://www.example.com/svn
Then I create my project at a folder like: /home/me/workspace/my_app
I want to Setup my svn client and ignore files like tmp/* log/* db/schema.rb and such, so what are the commands on console for that? If possible can you write what the full sequence of commands to set this up?
obs: I have found no GUI that suit my needs on Ubuntu kdesvn / rapidsvn :(
Using TortoiseSVN, you could simply use the ignore menu item, but I guess you're not using a GUI.
You can ignore single files by executing this in the containing directory:
svn propset svn:ignore filename .
Replace filename by the filename you want to ignore. This can also be a wildcard expression like *.suo. It can also be a directory like tmp.
you can define the prop svn:ignore
so in your directory where you want ignore file made :
svn propedit svn:ignore .
An editor is open an add your information into. Close it and your file are ignore
I make a call just like this:
value = ./simulated_annealing
Which is a C Object file, but Rails tells me it cannot find that file. I
put it in the same dir that the rest of the models files (since it's
called by one of those models), but I guess it should be in any other
place.
I've tried that outside Ruby and it works great.
What do I have to do?
The thing is, when you say:
./simulated_annealing
you're explicitly saying: run file named simulated_annealing which is found in the current directory. That's what the ./ means. If the file's located elsewhere you need to provide the path to it, or add that path to the environment variable $PATH. So, you should replace that line with:
/path/to/simulated_annealing
where /path/to represents the actual path.
The best option is to use an absolute path for running the program. For ex.,
you can create a directory "bin" under your rails application top level
directory. Place your program under "bin" directory. Then you can
execute the program something like:
cmd = "#{RAILS_ROOT}/bin/cbin arg1 arg2"
value = `#{cmd}`