Skip to content

Commit dddc9e8

Browse files
committed
fix sudo to work with all shells / environments
1 parent 9965420 commit dddc9e8

File tree

5 files changed

+19
-23
lines changed

5 files changed

+19
-23
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,10 @@ will be executed is "root". This can be changed by passing
462462
`user: "name"` with the second argument:
463463

464464
```javascript
465-
// will run: sudo -u root -i bash -c 'Hello world'
465+
// will run: echo 'echo Hello world' | sudo -u root -i bash
466466
transport.sudo('echo Hello world');
467467

468-
// will run sudo -u www -i bash -c 'Hello world'
468+
// will run echo 'echo Hello world' | sudo -u www -i bash
469469
transport.sudo('echo Hello world', {user: 'www'});
470470

471471
// further options passed (see `exec()`)

lib/transport/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var format = require('util').format
77
, errors = require('../errors')
88
, commands = require('./commands')
99
, queue = require('../utils/queue')
10-
, escapeQuotes = require('../utils').escapeQuotes;
10+
, escapeSingleQuotes = require('../utils').escapeSingleQuotes;
1111

1212
/**
1313
* A transport is the interface you use during flights. Basically they
@@ -148,10 +148,10 @@ Transport.prototype.exec = function(command, options) {
148148
* `user: "name"` with the second argument:
149149
*
150150
* ```javascript
151-
* // will run: sudo -u root -i bash -c 'Hello world'
151+
* // will run: echo 'echo Hello world' | sudo -u root -i bash
152152
* transport.sudo('echo Hello world');
153153
*
154-
* // will run sudo -u www -i bash -c 'Hello world'
154+
* // will run echo 'echo Hello world' | sudo -u www -i bash
155155
* transport.sudo('echo Hello world', {user: 'www'});
156156
*
157157
* // further options passed (see `exec()`)
@@ -190,8 +190,8 @@ Transport.prototype.sudo = function(command, options) {
190190
var user = options.user || 'root';
191191

192192
command = format('%s%s', this._execWith, command);
193-
command = escapeQuotes(command);
194-
command = format("sudo -u %s -i bash -c \"'%s'\"", user, command);
193+
command = escapeSingleQuotes(command);
194+
command = format("echo '%s' | sudo -u %s -i bash", command, user);
195195

196196
return this._exec(command, options);
197197
};

lib/utils/index.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,10 @@ exports.writeTempFile = function(str) {
1717
return fullpath;
1818
};
1919

20-
exports.escapeQuotes = function(str) {
20+
exports.escapeSingleQuotes = function(str) {
2121
if(!str) {
2222
return str;
2323
}
2424

25-
str = str.replace(/"/g, '\\"');
26-
str = str.replace(/'/g, "'\\''");
27-
28-
return str;
25+
return str.replace(/'/g, "'\\''");
2926
};

test/test.transport.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe('transport', function() {
9797

9898
expect(transport._exec.calledOnce).to.be.true;
9999
expect(transport._exec.lastCall.args).to.deep.equal([
100-
"sudo -u root -i bash -c \"''\"",
100+
"echo '' | sudo -u root -i bash",
101101
{}
102102
]);
103103
});
@@ -108,12 +108,12 @@ describe('transport', function() {
108108
transport.sudo('printf "hello world"');
109109

110110
expect(transport._exec.lastCall.args[0])
111-
.to.equal("sudo -u root -i bash -c \"\'printf \\\"hello world\\\"\'\"");
111+
.to.equal("echo 'printf \"hello world\"' | sudo -u root -i bash");
112112

113113
transport.sudo("printf 'hello world'");
114114

115115
expect(transport._exec.lastCall.args[0])
116-
.to.equal("sudo -u root -i bash -c \"'printf '\\''hello world'\\'''\"");
116+
.to.equal("echo 'printf '\\''hello world'\\''' | sudo -u root -i bash");
117117
});
118118

119119
it('should pass options to #_exec()', function() {
@@ -129,7 +129,7 @@ describe('transport', function() {
129129

130130
transport.sudo('cmd', { user: 'not-root' });
131131

132-
expect(transport._exec.lastCall.args[0]).to.equal("sudo -u not-root -i bash -c \"'cmd'\"");
132+
expect(transport._exec.lastCall.args[0]).to.equal("echo 'cmd' | sudo -u not-root -i bash");
133133
});
134134
});
135135

test/test.utils.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,14 @@ describe('utils', function() {
3737
});
3838
});
3939

40-
describe('#escapeQuotes()', function() {
40+
describe('#escapeSingleQuotes()', function() {
4141
it('should correctly escape single quotes', function() {
42-
var escapeQuotes = proxyquire('../lib/utils', {}).escapeQuotes;
42+
var escapeSingleQuotes = proxyquire('../lib/utils', {}).escapeSingleQuotes;
4343

44-
expect(escapeQuotes("'string'")).to.equal("'\\''string'\\''");
45-
expect(escapeQuotes('"string"')).to.equal('\\"string\\"');
46-
expect(escapeQuotes("\\'string\\'")).to.equal("\\'\\''string\\'\\''");
47-
expect(escapeQuotes('')).to.equal('');
48-
expect(escapeQuotes()).to.be.undefined;
44+
expect(escapeSingleQuotes("'string'")).to.equal("'\\''string'\\''");
45+
expect(escapeSingleQuotes("\\'string\\'")).to.equal("\\'\\''string\\'\\''");
46+
expect(escapeSingleQuotes('')).to.equal('');
47+
expect(escapeSingleQuotes()).to.be.undefined;
4948
});
5049
});
5150

0 commit comments

Comments
 (0)