I am seeing many times the question about execution of bash files inside rake (task) files.
My question is, how to execute a rake command inside the bash file?
I have a migrate.sh file inside each rails app on my server and I'm using a general publish.sh. All of this runs ok.
Then, I have a command like rake tmp:clear assets:clean log:clear RAILS_ENV=production inside each migrate.sh that gives me a rake: command not found error.
Help?
Basically rake is not resolved as the PATH variable is not correct. You can try doing echo $PATH. Also you can create a bash script and provide some environment variables required by rake like this:
#!/bin/bash
GEM_HOME=/home/tuxdna/.gems
SHELL=/bin/bash
USER=tuxdna
PATH=/home/tuxdna/.gems/bin:/usr/lib/ruby/gems/1.8/bin/:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
GEM_PATH=/home/tuxdna/.gems:/usr/lib/ruby/gems/1.8
cd ~/somesite
export RAILS_ENV=production
bundle exec rake mytask:task1
klashxx's supposition was correct. It was a permissions/profile issue. I had change my user to root to be able to do other previous tasks and found out that my root was not able to run rake tasks.
This will not be an issue on production server though.
Thanks klashxx
Related
I have this script that should be running from the /~ directory:
#!/bin/bash
APP=/root/apps/monitoring
cd $APP
git pull
rake assets:precompile RAILS_ENV=production
touch $APP/tmp/restart.txt
As you can see, it pulls new commits and updates the assets and restarts Apache. The problem is when it runs the line rake assets:precompile RAILS_ENV=production, It says:
Could not find proper version of rake (12.1.0) in any of the sources
Run `bundle install` to install missing gems.
Which is strange because I am supposed to be inside the app's folder (/root/apps/monitoring) when this command is executed. What I am doing wrong?
You may need to load rvm in the script (https://rvm.io/workflow/scripting) and may be select proper ruby/gemset.
Also you can consider using wrapper for bundle created with rvm wrapper
Please try
#!/bin/bash
APP=/root/apps/monitoring
cd $APP
git pull
bundle exec rake assets:precompile RAILS_ENV=production
touch $APP/tmp/restart.txt
With bundle exec it should work.
I run rake tasks using bash script wrappers. The trick is to use the source command to load in the rvm environment after the task is started
example.sh
#!/bin/bash
# change the directory
cd /home/ubuntu/GSeries
# load rvm ruby
source /home/ubuntu/.rvm/environments/ruby-2.4.2#mygemset
bundle exec rake db:prune_logs RAILS_ENV="production" &>> /home/ubuntu/GSeries/log/prune_logs.log
I have rake task which continuously need to be active. Whenever I ran it by command
RAILS_ENV=production rake jobs:abc
it works fine but when I close terminal rake job get stopped.So I found other solution on it by using nohup to run it in background.
I execute command:
nohup RAILS_ENV=production rake jobs:work &
but it gives error:
nohup: failed to run command ‘RAILS_ENV=production’: No such file or directory
Please suggest, to way execute rake task in a production environment.
Set the environment variable before the nohup command.
RAILS_ENV=production nohup rake jobs:work
Try this one
nohup rake jobs:work RAILS_ENV=production
I have commented the solution above as well
If you need nohup functionality, you should also consider screen.
RAILS_ENV=production screen -L rake jobs:work
It starts a new terminal which isn't bound to your current session.
To come back to your normal terminal, type Ctrl+a and then d. You can now log out safely without terminating the rake task.
As a bonus, you automatically get a log file in screenlog.0.
You can come back to your rake process by typing :
screen -r
I appreciate all the answers out there as to what bundle exec does, which is that it runs the following commands in the context of the Gemfile bundle. But why doesn't "rails server" need bundle exec? Seems like it should still apply.
The rails command runs from the executable inside the script folder. If you remove this folder, you can see that rails commands stop working. rake however runs differently.
What is the difference between using bin/rake and bundle exec rake.
And which is one preferred style?
bin/rake db:migrate
bundle exec rake db:migrate
bundle exec executes a command in the context of your application.
As each application can have different versions of gem used. Using bundle exec guarantees that you use the correct versions.
I use bundle exec always instead of rake because i have multiple applications running on my system.
Try to use bundle exec rake db:migrate always.
You can learn more about it here Official documentation
bin/rake is a kind of stub for the rake command from bundled Gems. It has exactly the same function as bundle exec rake. See http://bundler.io/v1.14/man/bundle-install.1.html and search for binstubs for more about stub. And also note that bin/rake and bin/rails are stubs generated by Rails, which are different in code from the stubs generated by bundler. However, they all serve the same purpose and have the same function.
You have 3 options on a typical system:
bin/rake db:migrate
rake db:migrate
bundle exec db:migrate
The first option is simply calling the path to the rake program, whose launcher can be found in the hidden /bin folder. This launcher is usually just a symlink to the program's content found in your /.rvm directory. You can find its original location by executing $ which rake, which will give you something like /home/ubuntu/.rvm/gems/ruby-2.2.3-p481#devonzuegel/bin/rake.
By default, the second option is essentially the same as the first on most systems. It's what is called an alias, which is basically just a shorthand command for some other program. This is defined somewhere in your shell settings as something like alias rake='/bin/rake'. It's possible that this alias is pointed to a different program on your machine though, so check that before taking my word for it.
When you use bundle exec you're telling bundler to ensure that only the gems and their specified versions from your Gemfile.lock are loaded. This will only work if you're in a directory that contains a Gemfile.lock or whose parent/grandparent directory contains one.
Running Rake tasks can be awkward.
The commands tend to be really long.
For example...
$ bundle exec rake some_project:clear_expired_sessions
Also, I may not always remember the exact name of some task I only use occasionally.
So I have to discover task's name first like this and then copy and paste it into the command line...
$ bundle exec rake -T some_project
I'm using Zsh on OS X with oh-my-zsh and the Rake plugin.
It provides tab-completion of Rake tasks, but you still have to type "bund exec rake" the completions are really slow to load -- several seconds on my machine.
Is there a more efficient way?
You can always add an alias to your .bashrc or your .bash_profile to avoid bundle exec rake in the future.
alias rake='bundle exec rake'
Of course now bundle exec is implicated whenever you run rake, its up to you to decide if you want that.
or for project specific (lets say your project is rails_blog)
alias rkblog=railsblogtasks()
function railsblogtasks(){
cd /path/to/blog/;
bundle exec rake -T;
end
alias rkblogrun=runblogtask()
function runblogtask(){
cd /path/to/blog/;
bundle exec rake $1;
end
Now $ rkblog will show all your rails_blog tasks and $ rkblogrun <task> will run any task in your rails_blog project. This can of course be refactored and abstracted, but there is a general idea.
One quick simplication:
task :example_alias => :environment do
Rake::Task[some_project:clear_expired_sessions].invoke
end
Then you can simply do
$ rake example_alias