mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
406 lines
19 KiB
HTML
406 lines
19 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Why does something work in my SSH session, but not in Capistrano?</title>
|
|
<link href='http://fonts.googleapis.com/css?family=Enriqueta' rel='stylesheet' type='text/css'>
|
|
<script type="text/javascript" src="//use.typekit.net/itm5ubu.js"></script>
|
|
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
|
|
<link rel="stylesheet" href="/css/foundation.css" />
|
|
<link rel="stylesheet" href="/css/capistrano.css">
|
|
<link rel="stylesheet" href="/css/social_foundicons.css" />
|
|
<link rel="stylesheet" href="/css/okaidia.css">
|
|
<script src="/js/vendor/custom.modernizr.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<script type="text/javascript">
|
|
var _gauges = _gauges || [];
|
|
(function() {
|
|
var t = document.createElement('script');
|
|
t.type = 'text/javascript';
|
|
t.async = true;
|
|
t.id = 'gauges-tracker';
|
|
t.setAttribute('data-site-id', '51c83c32613f5d7df70000bc');
|
|
t.src = '//secure.gaug.es/track.js';
|
|
var s = document.getElementsByTagName('script')[0];
|
|
s.parentNode.insertBefore(t, s);
|
|
})();
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
setTimeout(function(){var a=document.createElement("script");
|
|
var b=document.getElementsByTagName("script")[0];
|
|
a.src=document.location.protocol+"//dnn506yrbagrg.cloudfront.net/pages/scripts/0017/6418.js?"+Math.floor(new Date().getTime()/3600000);
|
|
a.async=true;a.type="text/javascript";b.parentNode.insertBefore(a,b)}, 1);
|
|
</script>
|
|
|
|
<script>
|
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
|
|
|
ga('create', 'UA-41970098-1', 'capistranorb.com');
|
|
ga('send', 'pageview');
|
|
</script>
|
|
<div class="header">
|
|
<div class="row">
|
|
<div class="large-12 column">
|
|
<a href="/" class="brand">
|
|
<img src="/images/CapistranoLogo.png" />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="row">
|
|
<div class="large-4 columns">
|
|
<ul class="side-nav">
|
|
<li><a href="https://www.harrow.io/" class="advertisment"><span class="label label-important">New</span> Hosted Capistrano for Teams</a></li>
|
|
<li class="divider"></li>
|
|
<h5>Overview</h5>
|
|
<li><a href="/documentation/overview/what-is-capistrano/">What is Capistrano?</a></li>
|
|
<!--<li><a href="/documentation/overview/introductory-demo-video/">Introductory Demo Video</a></li>-->
|
|
<li class="divider"></li>
|
|
<h5>Getting Started</h5>
|
|
<li><a href="https://github.com/capistrano/capistrano/blob/v3/README.md">The Readme, start here!</a></li>
|
|
<li><a href="/documentation/getting-started/installation/">Installation</a></li>
|
|
<li><a href="/documentation/getting-started/preparing-your-application/">Preparing Your Application</a></li>
|
|
<li><a href="/documentation/getting-started/authentication-and-authorisation/">Authentication & Authorisation</a></li>
|
|
<li><a href="/documentation/getting-started/cold-start/">Cold Start</a></li>
|
|
<li><a href="/documentation/getting-started/flow/">Flow</a></li>
|
|
<li><a href="/documentation/getting-started/rollbacks/">Rollbacks</a></li>
|
|
<li><a href="/documentation/getting-started/remote-file/">Remote file task</a></li>
|
|
<li class="divider"></li>
|
|
<h5>Framework Extensions</h5>
|
|
<li><a href="/documentation/frameworks/ruby-on-rails/">Ruby on Rails</a></li>
|
|
<li><a href="/documentation/frameworks/bundler/">Bundler</a></li>
|
|
<li><a href="/documentation/frameworks/rbenv-rvm-chruby/">Rbenv & RVM & chruby</a></li>
|
|
<!--<li class="divider"></li> -->
|
|
<!--<h5>Troubleshooting</h5> -->
|
|
<!--<li><a href="/documentation/troubleshooting/authentication/">SCM (Git) Authentication</a></li>-->
|
|
<!--<li><a href="/documentation/troubleshooting/connectivity/">Connectivity</a></li> -->
|
|
<!--[><li><a href="/documentation/troubleshooting/gateway-servers/">Gateway Servers</a></li><] -->
|
|
<!--<li><a href="/documentation/troubleshooting/agent-forwarding/">Agent Forwarding</a></li> -->
|
|
<!--<li><a href="/documentation/troubleshooting/sudo-password/">`sudo` Password</a></li> -->
|
|
<!--<li><a href="/documentation/troubleshooting/rvm-rbenv-nvm/">RVM, `rbenv` And `nvm`</a></li> -->
|
|
<li class="divider"></li>
|
|
<h5>FAQ</h5>
|
|
<li><a href="/documentation/faq/why-does-something-work-in-my-ssh-session-but-not-in-capistrano/">Why Does Something Work In An SSH Session, But Not In Capistrano?</a></li>
|
|
<!--<li><a href="/documentation/faq/should-i-use-capistrano-to-provision-my-servers/">Should I Use Capistrano To Provision My Servers?</a></li>-->
|
|
<li><a href="http://lee.hambley.name/2013/06/11/using-capistrano-v3-with-chef.html">Should I Use Capistrano To Provision My Servers?</a></li>
|
|
<!--<li class="divider"></li> -->
|
|
<!--<h5>Power Use-Cases</h5> -->
|
|
<!--<li><a href="/documentation/power-use-cases/integration-with-rake/">Integration With Rake</a></li> -->
|
|
<!--<li><a href="/documentation/power-use-cases/driving-tools-such-as-chef-solo/">Driving Tools Such As <em>Chef Solo</em></a></li>-->
|
|
<li class="divider"></li>
|
|
<h5>Legacy Documentation</h5>
|
|
<li><a href="https://github.com/capistrano/capistrano/wiki">Capistrano
|
|
v2</a></li>
|
|
<li class="divider"></li>
|
|
<h5>Recent Announcements</h5>
|
|
|
|
<li><a href="/2013/06/01/release-announcement.html"><span class="post-date">01 Jun 2013</span> Capistrano Version 3 Release Announcement</a></li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
<div class="large-8 column">
|
|
<div class="content">
|
|
<h2>Why does something work in my SSH session, but not in Capistrano?</h2>
|
|
<p>This is possibly one of the most complicated support questions that can be
|
|
asked, the only real answer is <strong><em>it depends</em></strong>.</p>
|
|
|
|
<p>It's really a question of which <em>kind</em> of shell Capistrano is using, it's a
|
|
matrix of possibilities concerning <code>login</code>, <code>non-login</code>, <code>interactive</code>, or
|
|
<code>non-interactive</code>.</p>
|
|
|
|
<p><strong>By default Capistrano always assigns a <code>non-login</code>, <code>non-interactive</code> shell.</strong></p>
|
|
|
|
<h2 id="toc_0">Shell Modes</h2>
|
|
|
|
<p>Unix shells can be started in one of three modes, an unnamed <em>basic</em> mode,
|
|
which almost never happens, as a <code>login</code> shell, or as an <code>inteactive</code> shell.</p>
|
|
|
|
<p>Depending which mode a shell starts in (and which shell you are using) this
|
|
will affect which startup (more commonly known as <em>dot</em>-files) files, if any
|
|
are loaded, here's more or less the matrix of what is loaded when:</p>
|
|
|
|
<h2 id="toc_1">What about the Capistrano option to assign a <code>pty</code>?</h2>
|
|
|
|
<p>This option has been hugely misleadingly used, if you ask SSH to provide a
|
|
<code>pty</code> you are effectively telling SSH that <em>"I'll connect this session to a
|
|
user terminal"</em>, thus programs on the receiving end expect that they can prompt
|
|
for input, and provide coloured output, etc. In short they think they're
|
|
talking to you over an interactive session, because by assigning a <code>pty</code>, Bash
|
|
has been started in <code>non-login</code>, <code>interactive</code> mode.</p>
|
|
|
|
<p>Read more about this:</p>
|
|
|
|
<ul>
|
|
<li><a href="https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html">In the "Bash Startup Files" section of the Bash
|
|
manual</a></li>
|
|
<li><a href="https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html">At Sam Stephenson's excellent <em>Unix shell initialization</em> wiki
|
|
page</a></li>
|
|
<li><a href="http://www.tldp.org/LDP/abs/html/intandnonint.html">Interactive and non-interactive shells and scripts
|
|
documentation</a></li>
|
|
</ul>
|
|
|
|
<h2 id="toc_2">How does what Capistrano does differ from an SSH session</h2>
|
|
|
|
<p>By default Capistrano prefers to start a <em>non-login, non-interactive
|
|
shell</em>, to try and isolate the environment and make sure that things work as
|
|
expected, regardless of any changes that might happen on the server side.</p>
|
|
|
|
<p>In contrast when you log into a machine with your terminal, into a regular
|
|
Bash session, the <code>--login</code> option to Bash is implied granting you a <code>login</code>
|
|
shell, and because you are in a terminal, ssh asks the ssh server to provide a
|
|
pty so that you may start an interactive session. Thus you get an <code>interactive
|
|
login</code> shell, the exact opposite of what we need for Capistrano!</p>
|
|
|
|
<h2 id="toc_3">How can I check?</h2>
|
|
|
|
<p>I actually had to look this up, most of the time it's common sense, but
|
|
<a href="http://unix.stackexchange.com/a/26782">stackoverflow to the rescue</a>, let's
|
|
figure this out!</p>
|
|
|
|
<p>First, we'll try a <em>real</em> SSH session, logging in via our terminal, and seeing
|
|
what happens:</p>
|
|
|
|
<div>
|
|
<pre data-line=''><code class='language-bash'>me@localhost $ ssh me@remote
|
|
me@remote $ [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
|
|
Interactive
|
|
me@remote $ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
|
|
Login shell</code></pre>
|
|
</div>
|
|
|
|
<p>Contrast that with what happens when we hand the command to run to the SSH
|
|
command line without logging in first...</p>
|
|
|
|
<div>
|
|
<pre data-line=''><code class='language-bash'>me@localhost $ ssh me@remote "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'"
|
|
Interactive
|
|
me@localhost $ ssh me@remote "shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'"
|
|
Not login shell</code></pre>
|
|
</div>
|
|
|
|
<p>Here we can see that Bash is still starting in <strong>interactive</strong> mode when we're
|
|
just running a single command, that's because the terminal we are using is
|
|
interactive, and SSH inherits that and passes that on to the remote server.</p>
|
|
|
|
<p>When we try the same with Capistrano we'll see yet another set of results; we
|
|
can have a very simple, Capfile, we don't even need to load the default
|
|
recipes to test this:</p>
|
|
|
|
<div>
|
|
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
|
|
task :query_interactive do
|
|
on 'me@remote' do
|
|
info capture("[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'")
|
|
end
|
|
end
|
|
task :query_login do
|
|
on 'me@remote' do
|
|
info capture("shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'")
|
|
end
|
|
end</code></pre>
|
|
</div>
|
|
|
|
<p>Gives us the following:</p>
|
|
|
|
<div>
|
|
<pre data-line=''><code class='language-bash'>me@localhost $ cap query_login
|
|
INFO Not login shell
|
|
me@localhost $ cap query_interactive
|
|
INFO Not interactive</code></pre>
|
|
</div>
|
|
|
|
<h2 id="toc_4"><a id="which_startup_files_loaded"></a>Which shell startup files do get loaded?</h2>
|
|
|
|
<p>Best explained with this diagram, yes it's that complicated:</p>
|
|
|
|
<figure class="panel">
|
|
<img src="/images/BashStartupFiles1.png" title="Bash Startup Files" alt="Bash Startup Files" />
|
|
<figcaption>
|
|
<p>Source: <a href="http://www.solipsys.co.uk/new/BashInitialisationFiles.html">http://www.solipsys.co.uk/new/BashInitialisationFiles.html</a></p>
|
|
</figcaption>
|
|
</figure>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!--<div class="container"> -->
|
|
<!-- <h1 class="title"><a href="/">Capistrano</a></h1>-->
|
|
<!-- <a class="extra" href="/">home</a> -->
|
|
<!-- </div> -->
|
|
|
|
<!-- <p>This is possibly one of the most complicated support questions that can be
|
|
asked, the only real answer is <strong><em>it depends</em></strong>.</p>
|
|
|
|
<p>It's really a question of which <em>kind</em> of shell Capistrano is using, it's a
|
|
matrix of possibilities concerning <code>login</code>, <code>non-login</code>, <code>interactive</code>, or
|
|
<code>non-interactive</code>.</p>
|
|
|
|
<p><strong>By default Capistrano always assigns a <code>non-login</code>, <code>non-interactive</code> shell.</strong></p>
|
|
|
|
<h2 id="toc_0">Shell Modes</h2>
|
|
|
|
<p>Unix shells can be started in one of three modes, an unnamed <em>basic</em> mode,
|
|
which almost never happens, as a <code>login</code> shell, or as an <code>inteactive</code> shell.</p>
|
|
|
|
<p>Depending which mode a shell starts in (and which shell you are using) this
|
|
will affect which startup (more commonly known as <em>dot</em>-files) files, if any
|
|
are loaded, here's more or less the matrix of what is loaded when:</p>
|
|
|
|
<h2 id="toc_1">What about the Capistrano option to assign a <code>pty</code>?</h2>
|
|
|
|
<p>This option has been hugely misleadingly used, if you ask SSH to provide a
|
|
<code>pty</code> you are effectively telling SSH that <em>"I'll connect this session to a
|
|
user terminal"</em>, thus programs on the receiving end expect that they can prompt
|
|
for input, and provide coloured output, etc. In short they think they're
|
|
talking to you over an interactive session, because by assigning a <code>pty</code>, Bash
|
|
has been started in <code>non-login</code>, <code>interactive</code> mode.</p>
|
|
|
|
<p>Read more about this:</p>
|
|
|
|
<ul>
|
|
<li><a href="https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html">In the "Bash Startup Files" section of the Bash
|
|
manual</a></li>
|
|
<li><a href="https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html">At Sam Stephenson's excellent <em>Unix shell initialization</em> wiki
|
|
page</a></li>
|
|
<li><a href="http://www.tldp.org/LDP/abs/html/intandnonint.html">Interactive and non-interactive shells and scripts
|
|
documentation</a></li>
|
|
</ul>
|
|
|
|
<h2 id="toc_2">How does what Capistrano does differ from an SSH session</h2>
|
|
|
|
<p>By default Capistrano prefers to start a <em>non-login, non-interactive
|
|
shell</em>, to try and isolate the environment and make sure that things work as
|
|
expected, regardless of any changes that might happen on the server side.</p>
|
|
|
|
<p>In contrast when you log into a machine with your terminal, into a regular
|
|
Bash session, the <code>--login</code> option to Bash is implied granting you a <code>login</code>
|
|
shell, and because you are in a terminal, ssh asks the ssh server to provide a
|
|
pty so that you may start an interactive session. Thus you get an <code>interactive
|
|
login</code> shell, the exact opposite of what we need for Capistrano!</p>
|
|
|
|
<h2 id="toc_3">How can I check?</h2>
|
|
|
|
<p>I actually had to look this up, most of the time it's common sense, but
|
|
<a href="http://unix.stackexchange.com/a/26782">stackoverflow to the rescue</a>, let's
|
|
figure this out!</p>
|
|
|
|
<p>First, we'll try a <em>real</em> SSH session, logging in via our terminal, and seeing
|
|
what happens:</p>
|
|
|
|
<div>
|
|
<pre data-line=''><code class='language-bash'>me@localhost $ ssh me@remote
|
|
me@remote $ [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
|
|
Interactive
|
|
me@remote $ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
|
|
Login shell</code></pre>
|
|
</div>
|
|
|
|
<p>Contrast that with what happens when we hand the command to run to the SSH
|
|
command line without logging in first...</p>
|
|
|
|
<div>
|
|
<pre data-line=''><code class='language-bash'>me@localhost $ ssh me@remote "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'"
|
|
Interactive
|
|
me@localhost $ ssh me@remote "shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'"
|
|
Not login shell</code></pre>
|
|
</div>
|
|
|
|
<p>Here we can see that Bash is still starting in <strong>interactive</strong> mode when we're
|
|
just running a single command, that's because the terminal we are using is
|
|
interactive, and SSH inherits that and passes that on to the remote server.</p>
|
|
|
|
<p>When we try the same with Capistrano we'll see yet another set of results; we
|
|
can have a very simple, Capfile, we don't even need to load the default
|
|
recipes to test this:</p>
|
|
|
|
<div>
|
|
<pre data-line=''><code class='language-ruby'># Capistrano 3.0.x
|
|
task :query_interactive do
|
|
on 'me@remote' do
|
|
info capture("[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'")
|
|
end
|
|
end
|
|
task :query_login do
|
|
on 'me@remote' do
|
|
info capture("shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'")
|
|
end
|
|
end</code></pre>
|
|
</div>
|
|
|
|
<p>Gives us the following:</p>
|
|
|
|
<div>
|
|
<pre data-line=''><code class='language-bash'>me@localhost $ cap query_login
|
|
INFO Not login shell
|
|
me@localhost $ cap query_interactive
|
|
INFO Not interactive</code></pre>
|
|
</div>
|
|
|
|
<h2 id="toc_4"><a id="which_startup_files_loaded"></a>Which shell startup files do get loaded?</h2>
|
|
|
|
<p>Best explained with this diagram, yes it's that complicated:</p>
|
|
|
|
<figure class="panel">
|
|
<img src="/images/BashStartupFiles1.png" title="Bash Startup Files" alt="Bash Startup Files" />
|
|
<figcaption>
|
|
<p>Source: <a href="http://www.solipsys.co.uk/new/BashInitialisationFiles.html">http://www.solipsys.co.uk/new/BashInitialisationFiles.html</a></p>
|
|
</figcaption>
|
|
</figure>
|
|
-->
|
|
|
|
<!--</div> [> /container <] -->
|
|
|
|
<footer>
|
|
<div class="row">
|
|
<div class="large-4 columns">
|
|
<ul>
|
|
<li><a href="/about">About Capistrano</a></li>
|
|
<li><a href="https://github.com/capistrano/capistrano/blob/master/CONTRIBUTING">Contributing</a></li>
|
|
<li><a href="https://rubygems.org/gems/capistrano/versions">Releases</a></li>
|
|
<li><a href="/documentation/upgrading">Upgrading</a></li>
|
|
<li><a href="/security">Security</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="large-4 columns">
|
|
<ul>
|
|
<li><a href="http://stackoverflow.com/questions/tagged/capistrano">StackOverflow</a></li>
|
|
<li><a href="https://groups.google.com/forum/#!forum/capistrano">Mailing List</a></li>
|
|
<li><a href=".... ">Commercial Support</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="large-4 columns">
|
|
<ul class="social icons">
|
|
<li><a href="//twitter.com/capistranorb"><i class="foundicon-twitter"></i></a></li>
|
|
<li><a href="//github.com/capistrano"><i class="foundicon-github"></i></a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
|
|
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
|
|
<script>
|
|
if (!window.jQuery) {
|
|
document.write('<script src="/js/jquery-1.7.min"><\/script>');
|
|
}
|
|
</script>
|
|
<script src="/js/jquery.githubRepoWidget.min.js"></script>
|
|
<script src="/js/prism.js"></script>
|
|
<script src="/js/prism.ruby.js"></script>
|
|
<a href="https://github.com/capistrano/documentation"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png" alt="Fork me on GitHub"></a>
|
|
</body>
|
|
</html>
|