Bonsoir,

J'ai une petite question concernant le SSH avec PHP. En effet, jusqu'à maintenant, je mets tout les chemins en absolu, ce qui devient redondant et, on est d'accord, pas très sympa à écrire.

Le code actuel

Le code est dans un système d'auto-déploiement parce que je suis assez paresseux de faire toutes les commandes nécessaires pour mettre en place le site. Pour info, je parviens à me connecter sur la machine distante avec une paire de clefs SSH
Je vous montre que la partie intéressante du système, celle qui exécute les commandes SSH

deploy.php

Console::log('Envoi du fichier temporaire (' . \utilphp\util::size_format(filesize($tempdir . '/blog.tar.gz'), 2) . ')');
$ssh->send_file($tempdir . '/blog.tar.gz', '/tmp/blog.tar.gz');

Console::log('Décompression...');
$ssh->execute('cd /var/www && tar -zxf /tmp/blog.tar.gz');

$ssh->execute('rm /var/www/blog/.idea -Rf');
$ssh->execute('rm /var/www/blog/deploy.php');
$ssh->execute('rm /var/www/blog/public/assets/node_modules -Rf');
$ssh->execute('rm /var/www/blog/vendor -Rf');
$ssh->execute('unlink /var/www/blog/public/themes');

Console::set_prefix('Composer');
Console::log('Installation');
$ssh->execute('cd /var/www/blog && /home/l4p1n/bin/composer install', 300);

Console::log('Optimisation de l\'autoloader');
$ssh->execute('cd /var/www/blog && /home/l4p1n/bin/composer du -o', 300);

Console::set_prefix('NPM');
Console::log('Installation des paquets');
$ssh->execute('cd /var/www/blog/public/assets && /usr/bin/npm install', 300);

Console::set_prefix('Links');
$ssh->execute('ln -s /var/www/blog/public/assets/node_modules/semantic-ui-css/themes/ /var/www/blog/public/themes');

$ssh->send_file(...) fait un coup de ssh2_scp_send avec les bons paramètres et $ssh->execute fait un coup de ssh2_exec avec les paramètres qui faut et en bloquant le stream jusqu'à détection de chaine de caractères qui demande à la méthode de se terminer.
Comme vous pouvez le constater, soit je cd dans le répertoire, soit je donne le chemin absolu.
Pour ceux qui veulent la méthode execute

       if(!$this->is_auth){
            throw new SSHException('Authentifiez vous d\'abord');
        }

        $this->log($command);

        $sentinel = $this->generate_sentinel();
        // Détecteur de commande finie
        $command .= ' && echo ' . $sentinel;
        $stream = ssh2_exec($this->ssh, $command);
        stream_set_blocking($stream, true);

        $data = '';
        $start = time();
        while(true){
            // On boucle jusqu'à avoir le détecteur de commande finie
            $bytes = fread($stream, 4096);
            $data .= $bytes;

            if($display){
                echo $bytes;
            }

            if(strpos($data, $sentinel) !== false){
                fclose($stream);
                break;
            }else if(time() - $start > $timeout){
                fclose($stream);
                throw new SSHException('Timeout atteint pour la commande ' . $command);
            }
        }

        return $data;

La machine locale tourne sous Xubuntu et la machine distante tourne sous Raspbian.
En gros la question: Est-ce nécessaire de mettre les chemins absolus partout ou bien le fait de cd dans le répertoire cible dans une commande séparée des autres est suffisant ?

5 réponses


Kareylo
Réponse acceptée

Tu peux toujours utiliser le cd et ensuite exécuter la commande en chemin relatif, bien sûr.

Dans le pire des cas, utilise une variable ave la base de ton chemin, ça fait toujours redondant, mais toujours plus facile à écrire.

$www = '/var/www';
$blog = $www . '/blog';

Pour faire par exemple :

$ssh->execute($blog . '/home/l4p1n/bin/composer install', 300);
l4p1n
Auteur

C'est déjà plus court à écrire :')
Mais cela ne répond pas trop à ma question: est-ce que j'ai besoin de toujours mettre le chemin absolu partout ou bien je peux juste cd dans une commande et exécuter le reste des commandes en chemin relatif ?

@Kareyleylo à condition de rester dans le même contexte
je n'ai pas testé mais est-ce que le $stream correspond au contexte ?
il faut plutôt ouvrir un shell avec ssh2_shell

l4p1n
Auteur

J'ai fait mes petites recherches sur Internet sur ssh2_shell et apparament le stream retourné est comme un fichier.
Je colle un bout de code que j'ai pu trouver sur la doc de ssh2_shell:

<?php

$con=ssh2_connect('192.168.0.1', 22);
ssh2_auth_password($con, 'user', 'password');
$shell=ssh2_shell($con, 'xterm');
fwrite( $shell, 'cd /dir_one;'.PHP_EOL);
fwrite( $shell, 'ls -la;'.PHP_EOL);
fwrite( $shell, 'cd /dir_two;'.PHP_EOL);
fwrite( $shell, 'ls -la;'.PHP_EOL);

En ce qui concerne le stream de ssh2_exec, ça permet de bloquer le script avec stream_set_blocking et aussi de récupérer les sorties STDIO et STDERR.
Toujours dans mes recherches, j'ai pu constater que les gens utilisent tous les chemins absolus que ce soit pour faire un ls ou bien pour pointer sur un fichier/répertoire.