backintime icon indicating copy to clipboard operation
backintime copied to clipboard

Incompatible remote shell (was: Can't create folder (because of fish shell on remote))

Open TriplEight opened this issue 1 year ago • 4 comments
trafficstars

Spent an hour checking that everything else works. Please at least don't let this fail silently. cc #470

backintime-qt --backup:

DEBUG: [common/sshtools.py:664 SSH.checkRemoteFolder] Call command: ssh -o ServerAliveInterval=240 -o LogLevel=Error -o IdentityFile=/home/user/.ssh/backup -o Ciphers=aes192-ctr -p 22 [email protected] d=0;test -e "/run/media/user/share/backups" || d=1;test $d -eq 1 && mkdir "/run/media/user/share/backups"; err=$?;test $d -eq 1 && exit $err;test -d "/run/media/user/share/backups" || exit 11;test -w "/run/media/user/share/backups" || exit 12;test -x "/run/media/user/share/backups" || exit 13;exit 20
DEBUG: [common/sshtools.py:674 SSH.checkRemoteFolder] Command returncode: 127

remote test:

$ ssh -o ServerAliveInterval=240 -o LogLevel=Error -o IdentityFile=/home/user/.ssh/backup -o Ciphers=aes128-ctr -p 22 [email protected] d=0;test -e "/mounts/share/backups" || d=1;test $d -eq 1 && mkdir "/mounts/share/backups"; err=$?;test $d -eq 1 && exit $err;test -d "/mounts/share/backups" || exit 11;test -w "/mounts/share/backups" || exit 12;test -x "/mounts/share/backups" || exit 13;exit 20
fish: Unsupported use of '='. In fish, please use 'set d 0'.
d=0
^~^
mkdir: cannot create directory ‘/mounts/share/backups’: No such file or directory
exit

TriplEight avatar Oct 15 '24 18:10 TriplEight

Hello Denis,

Thank you for taking the time to report the bug and providing the details. I appreciate your feedback.

I see several options how to "solve" this issue. Please let me know what you think from your perspective and experience. Maybe you see another option?

bash-only: We could check for the remote shell and give an error message if it is not bash. Easy to implement.

allowlist: Check the remote shell and see if it is a shell in an allowlist.

denylist: The opposite of an allowlist.

posix: Force posix shells. ~~To my knowledge fish should does follow posix standard.~~ Fish does not adher to posix, so it would not be allowed by BIT. But our own shell calls also not posix complaint. There might be some linters/checkers.

force bash: Isn't it possible to force using bash on remote? Not ssh -o ServerAliveInterval=240 foobar but ssh -o ServerAliveInterval=240 bash -c "foobar"?

Let me know what you think?

Please see the projects background information to get an idea about our workflow and priorities:

Best regards, Christian

buhtz avatar Oct 16 '24 06:10 buhtz

https://www.mail-archive.com/[email protected]/msg00119.html

buhtz avatar Nov 27 '24 11:11 buhtz

Of the options you've proposed, I believe the most robust and maintainable solution would be the force bash approach. We can modify the SSH command to explicitly run the commands in bash, which would resolve the shell compatibility issues. Here's a draft implementation:

ssh_cmd = [
    'ssh', 
    '-o', 'ServerAliveInterval=240', 
    '-o', 'LogLevel=Error', 
    '-o', 'IdentityFile=/home/user/.ssh/backup', 
    '-o', 'Ciphers=aes192-ctr', 
    '-p', '22', 
    f'{user}@{host}', 
    'bash', '-c', 
    f'd=0;test -e "{remote_path}" || d=1;test $d -eq 1 && mkdir "{remote_path}"; err=$?;test $d -eq 1 && exit $err;test -d "{remote_path}" || exit 11;test -w "{remote_path}" || exit 12;test -x "{remote_path}" || exit 13;exit 20'
]
  • This ensures the command runs in bash regardless of the user's default shell (and this issue appeared exactly because of it).
  • Minimal changes to existing code
  • Consistent behavior across different remote systems
  • Doesn't require complex shell detection or allowlisting

The posix and allowlist/denylist approaches seem more complicated and potentially less reliable. Forcing bash directly is a straightforward solution that should work consistently.

TriplEight avatar Dec 16 '24 16:12 TriplEight

I do agree. See #1965

buhtz avatar Dec 17 '24 06:12 buhtz

@buhtz

I have exactly the same issue. Backups to remote host stopped working (silently) after I changed the default shell to fish on the remote host. If you are going to force bash for the shell commands (which I'm ok with), please make sure you don't hardcode its path (like /usr/bin/bash). Its path may be different in different distros.

andreyfedoseev avatar Jul 18 '25 18:07 andreyfedoseev