When one calls
multipass exec from a shell, the whole command is first parsed by the shell one is in. The result of that parsing is what the multipass client gets in its
For example, when
multipass exec primary -- ls ~ is entered on a Linux shell, the tilde is translated to the calling user’s local home before the command is passed to multipass. But that is not the case on a Windows PowerShell, because “~” does not have the same meaning there.
Multipass then executes the command in the given instance as if there was no further shell in the middle (I say “as if” because the reality is a little more complicated). This is slightly different from what one would get with SSH:
$ multipass exec mp-builder -- python3 -c 'import sys; print(sys.argv)' foo bar ['-c', 'foo', 'bar'] $ ssh -i /var/root/Library/Application\ Support/multipassd/ssh-keys/id_rsa firstname.lastname@example.org python -c 'import sys; print(sys.argv)' foo bar bash: -c: line 1: syntax error near unexpected token `sys.argv' bash: -c: line 1: `python -c import sys; print(sys.argv) foo bar'
With SSH, the whole command would need to be quoted.
Note that one can still have another shell parse the command in the instance with
multipass exec, it just needs to be called explicitly:
$ multipass exec calm-woodcock -- sh -c 'ls -a ~' . .. .bash_logout .bashrc .cache .profile .ssh
This behaves the same regardless of the host platform. Without
sh -c, it also fails on all platforms (although possibly in different ways, depending on whether or not the nested command is quoted). It makes for a more consistent cross-platform experience.