Skip to content

Commit c7251ef

Browse files
committed
Exec: Store current working directory
1 parent c56875c commit c7251ef

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

src/Ssh/Exec.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,42 @@
1313
*/
1414
class Exec extends Subsystem
1515
{
16+
protected $cwd;
17+
protected $storeCwd = false;
18+
1619
protected function createResource()
1720
{
1821
$this->resource = $this->getSessionResource();
1922
}
2023

2124
public function run($cmd, $pty = null, array $env = array(), $width = 80, $height = 25, $width_height_type = SSH2_TERM_UNIT_CHARS)
2225
{
23-
$cmd .= ';echo -ne "[return_code:$?]"';
26+
if ($this->cwd && $this->storeCwd) {
27+
$cmd = 'cd '.escapeshellarg($this->cwd).';'.$cmd;
28+
}
29+
30+
$cmd .= ';echo -ne "\\0" "$?" "\\0";pwd';
2431
$stdout = ssh2_exec($this->getResource(), $cmd, $pty, $env, $width, $height, $width_height_type);
2532
$stderr = ssh2_fetch_stream($stdout, SSH2_STREAM_STDERR);
2633
stream_set_blocking($stderr, true);
2734
stream_set_blocking($stdout, true);
2835

2936
$output = stream_get_contents($stdout);
30-
preg_match('/\[return_code:(.*?)\]/', $output, $match);
31-
if ((int) $match[1] !== 0) {
32-
throw new RuntimeException(stream_get_contents($stderr), (int) $match[1]);
37+
preg_match('/^(.*)\\0 (\d+) \\0([^\\0]+)$/s', $output, $match);
38+
39+
list($_, $output, $retcode, $cwd) = $match;
40+
41+
$this->cwd = rtrim($cwd, "\r\n");
42+
43+
if ((int) $retcode !== 0) {
44+
throw new RuntimeException(stream_get_contents($stderr), (int) $retcode);
3345
}
3446

35-
return preg_replace('/\[return_code:(.*?)\]/', '', $output);
47+
return $output;
48+
}
49+
50+
public function setStoreCwd($store)
51+
{
52+
$this->storeCwd = $store;
3653
}
3754
}

tests/Ssh/FunctionalTests/ExecTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,28 @@ public function testExecuteErrorOutput()
5858

5959
$this->assertEquals('', trim($output));
6060
}
61+
62+
public function testExecuteWithStoreCwd()
63+
{
64+
$configuration = new Configuration('localhost');
65+
$authentication = new Password(TEST_USER, TEST_PASSWORD);
66+
$session = new Session($configuration, $authentication);
67+
68+
$exec = $session->getExec();
69+
$exec->setStoreCwd(true);
70+
71+
$output = $exec->run('pwd');
72+
$this->assertEquals(getenv('HOME'), trim($output));
73+
74+
$exec->run('cd /');
75+
76+
$output = $exec->run('pwd');
77+
$this->assertEquals('/', trim($output));
78+
79+
$exec->run('cd ~');
80+
81+
$output = $exec->run('pwd');
82+
$this->assertEquals(getenv('HOME'), trim($output));
83+
}
6184
}
62-
85+

0 commit comments

Comments
 (0)