Using bash shell when logging into FreeBSD ssh

I'm searching a way to be sure my commands are executed by bash on some FreeBSD 11 machines that use csh as default shell.

The following is my code that works on Linux CentOS / Debian / MacOS X / pfSense 2.3 (running on FreeBSD 10.3) and even Windows 10 bash, but doesn't work on FreeBSD 11

cat "/some/filelist" | ssh -i "/home/user/.ssh/some_key" user@freebsd11  'bash -c "while read -r file; do stat -f \"%N;%c;%m\" \"\$file\"; done | sort"'

Output of the previous command on FreeBSD 11 seems to be a csh error message

Unmatched ".

When checking which shell runs, it seems that csh runs. The following returns 'csh'

ssh -i /home/user/.ssh/some_key user@freebsd11 'bash -c "echo $0"'

As of my understandings, BSD systems do not allow changing shell, unless using a heredoc, but I can't send cat "/some/filelist" using a heredoc.

Of course, bash is installed and can be executed. I'm not interested in changing the default shell of the users on FreeBSD.

Any ideas here ?

My best guess would be to divide the problem:

1/ send the file with cat /some/filelist | ssh [..] 'cat > somefile'

2/ use the sent file in a heredoc

ssh [..] 'bash -s' << 'EOF'
while read -r file; do stat -f "%N;%c;%m" "$file" | sort; done < "$somefile"
'EOF'

This solution could work but is messy, makes 2 connections instead of one and won't work if remote can't write the 'somefile' for some reason.


Solution 1:

If you simplify your command line, the shell likely won't matter. This should likely work

ssh </some/filelist -i /home/user/.ssh/some_key user@freebsd11 xargs -n 1 stat -f \"%N;%c;%m\" | sort

Alternatively, you may want to change the default shell to bash for the particular user you are ssh-ing to - see the chsh(1) command.

Solution 2:

Use ansible. You don't need to add any additional software on the target machines and, arguably, it simplifies what you need to do. ansible uses standard ssh to connect to the machines, sudo, pfexec or doas are available if you need to run with privileges, and you can choose which user to connect as, and which user to execute as.

If the actual task is to perform stat on a list of files, there's already a module for that, and a lookup to iterate over the lines of a file:

---
- hosts: freebsd11:pfsense
  gather_facts: yes
  tasks:

  - name: stat a list of files
    stat: "{{ item }}"
    with_lines:
     - cat /path/to/list_of_files

If the task is an arbitrary shell command that needs to be executed in the target machine using bash, there's also a module for that:

---
- hosts: freebsd11:pfsense
  gather_facts: yes
  tasks:

  - name: execute shell script using bash
    shell: cat < /tmp/*txt
      args:
        executable: /bin/bash