backintime
backintime copied to clipboard
Incompatible remote shell (was: Can't create folder (because of fish shell on remote))
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
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
https://www.mail-archive.com/[email protected]/msg00119.html
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.
I do agree. See #1965
@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.