New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue executing a command within a directory #719
Comments
Please see the SSHKit (the cap backend driver). There's no way to apply The command must be formatted as per the examples in SSHkit's EXAMPLES.md On Saturday, October 19, 2013, Rahul Sekhar wrote:
Lee Hambleyhttp://lee.hambley.name/ |
So we should use it like this: within release_path do
execute "pwd"
execute "ls"
end @leehambley right? |
Unless you have a good reason not to do so, yes. If you write commands with spaces in their names the complexity for correct shell escaping goes through the roof, imagine the example: within release_path do
execute "rm -rf some file"
end Its impossible to know which spaces should be escaped (probably the user meant to type For that reason, if people wish to use spaces in their commands, they are free to do something like this: execute <<-EOCOMMAND
(
cd #{release_path};
pwd && ls;
)
EOCOMMAND We (the core team) are of the opinion that our decision makes sense, although admittedly from outside it's not immediately clear the reasoning behind that. |
@freemanoid Or you can do:
This is because should_map? in command.rb ( SSHKit ) interrupt to_command to make 'within' construction ( adding 'cd foo && ' ) . |
Instead of manually running a "cd" command, "within" blocks are used. Instead of manually setting the RESQUE_ENV environment variable when running commands, "with" blocks are used (and RAILS_ENV is added to the default environment in config/deploy/production.rb and staging.rb files, so it is used in all commands). Instead of manually running "bundle exec god" every time, a :god key is added to the SSHKit command map so that the :god command can be executed by capistrano and actually a "bundle exec god" is executed in the remote servers. Most of these are features of SSHKit, which is the library that powers Capistrano 3: https://github.com/capistrano/sshkit An important limitation of SSHKit is that "execute" cannot be passed a command string with whitespaces in it. Instead several strings (without whitespaces) can be passed, each one with part of the whole command, and when running it in the remote servers SSHKit concatenates all of them with witespaces between them. It makes for an awkward syntax but devs seem to think it unavoidable. For more details see: capistrano/capistrano#719
Sorry, as someone who just picked up Cap3 today, this is kind of nutty. The very first thing you're going to do when learning capistrano is to try and restart your server after getting your code deployed. It took me about 3 hours to debug why the code below executes under release_path
while
executes under $HOME Is there a good reason why the latter example shouldn't throw an error, as it's not going to do what it looks like it's going to do? I've looked at the SSHKit examples. They are useful, but while there are some nice gems in there, it's really, really, hard to try and derive the DSL that they're using. I'm not a Rake expert, but I'm reasonably competent with UNIX. I'm guessing that there are other people like me trying to use capistrano. I have a fork all ready to go for a README update, but really, I have no clue what to write, other than @pandora2000 or @leehambley s' suggestions above. For example, one of the SSHKit examples:
Really, really, stupid question: how is the :touch symbol defined, what's its path, what's its env, and why is that syntax preferred over "execute 'touch, 'somefile'"? Thanks, Andy |
I think there is no 'good' reason, but a problem of implementation.
doesn't succeed is the implementation set a prefix (in this case, cd to releath_path) to a command only when the command has no space. Some code do this, and this should be improved I think. Symbol :touch means nothing but 'touch' unless you replace it with
|
For whatever it's worth about 2 weeks ago large new sections were added to docs, and README explaining this. There's a good reason, and it's throughly documented and discussed here, at the mailing list, and importantly documented. |
Just as @leehambley said, there is a good reason.The reason has to do with proper shell escaping and how it is damn near impossible to do for generic strings. It's even on this ticket right at the top. This is mostly SSHKit territory, has nothing to do with rake or tasks, so look up the command map documentation and examples in the SSHKit documentation. It has been expanded and clarified quite recently. |
+1 to everything @andyzei said I don't understand why you wouldn't just execute the command, as-is. If the user forgot to escape their spaces, so what? That doesn't seem like capistrano's problem, nor is it capistrano's problem to protect a user from themselves. Bash doesn't care if you mistype a bash command, why would capistrano? So this "safety feature" really results in an awfully inconsistent/difficult-to-follow API, imo. |
You are free to use any other piece of software that more closely aligns When we have bugs we fix them, when features or caveats are difficult to Sent from my Nexus 5.
|
I mean, is there any practical reason other than trying to protect a user from themselves being bad at bash? Are there other disastrous consequences that could stem from this? Or...something else? My post was not meant to be offensive, I was (and still am) simply wondering why you believe this way is better. |
Years of watching people screw things up... we had to make a decision, and the command map function is valuable enough to justify making this slightly (for some experienced people) weird API. IT's not optimal, by any means, but given how |
@leehambley I completely follow the reasoning for why this behaves as it does, but I'm wondering: given the "inconsistency" and the fact the right way 95% of the time is to set the command without white space, would you consider logging a notice to the console if a command is included with whitespace in it? There would naturally need to be some way to disable the notice for those cases where someone knows what they're doing. |
The problem is both are equally valid ways to use the APIs, so warning on
|
This is the same behavior as Ruby's |
While writing a task, this works fine and executes within "/some/path":
This does not - it executes within the
deploy_to
path:In fact, it seems like executing a command with whitespace in it does not work as expected in a
within
block.The text was updated successfully, but these errors were encountered: