aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2022-08-04 13:57:28 +1200
committerTom Ryder <tom@sanctum.geek.nz>2022-08-04 13:57:28 +1200
commit092ec85c19f3c7809df522f58004a87dbec476d3 (patch)
tree8a84d613e7340523225f1359aca7d78bbc7b2a39
parentUse long GDB option (diff)
downloaddotfiles-092ec85c19f3c7809df522f58004a87dbec476d3.tar.gz
dotfiles-092ec85c19f3c7809df522f58004a87dbec476d3.zip
Support SSH many-Host lines and config subfiles
-rw-r--r--README.md2
-rw-r--r--bash/bash_completion.d/_ssh_config_hosts.bash29
-rw-r--r--bin/sls.sh3
-rw-r--r--bin/slsf.awk29
-rw-r--r--man/man1/sls.1df8
-rw-r--r--man/man1/slsf.1df8
-rw-r--r--man/man7/dotfiles.7df4
-rw-r--r--vim/filetype.vim15
8 files changed, 64 insertions, 34 deletions
diff --git a/README.md b/README.md
index d8156671..e59cb5e0 100644
--- a/README.md
+++ b/README.md
@@ -417,7 +417,7 @@ interactive shells.
These scripts are installed by the `install-bin` target:
- Three SSH-related scripts:
- - `sls(1df)` prints hostnames read from a `ssh_config(5)` file. It uses
+ - `sls(1df)` prints hostnames read from `ssh_config(5)` files. It uses
`slsf(1df)` to read each one.
- `sra(1df)` runs a command on multiple hosts read from `sls(1df)` and
prints output.
diff --git a/bash/bash_completion.d/_ssh_config_hosts.bash b/bash/bash_completion.d/_ssh_config_hosts.bash
index 0959f52b..16265e8a 100644
--- a/bash/bash_completion.d/_ssh_config_hosts.bash
+++ b/bash/bash_completion.d/_ssh_config_hosts.bash
@@ -3,23 +3,28 @@ _ssh_config_hosts() {
# Iterate through SSH client config paths
local config
- for config in "$HOME"/.ssh/config /etc/ssh/ssh_config ; do
+ for config in /etc/ssh/ssh_config.d/*.conf /etc/ssh/ssh_config \
+ "$HOME"/.ssh/config.d/*.conf "$HOME"/.ssh/config ; do
[[ -e $config ]] || continue
- # Read 'Host' options and their first value from file
- local option value ci
- while read -r option value _ ; do
+ # Read 'Host' options and their patterns from file
+ local option value patterns pattern ci
+ while read -r option value ; do
[[ $option == Host ]] || continue
+ read -a patterns -r \
+ < <(printf '%s\n' "$value")
# Check host value
- case $value in
- # No empties
- '') ;;
- # No wildcards
- *'*'*) ;;
- # Found a match; print it
- "$2"*) COMPREPLY[ci++]=$value ;;
- esac
+ for pattern in "${patterns[@]}" ; do
+ case $pattern in
+ # No empties
+ '') ;;
+ # No wildcards
+ *'*'*) ;;
+ # Found a match; print it
+ "$2"*) COMPREPLY[ci++]=$pattern ;;
+ esac
+ done
done < "$config"
done
diff --git a/bin/sls.sh b/bin/sls.sh
index 55c1dfc7..9741144a 100644
--- a/bin/sls.sh
+++ b/bin/sls.sh
@@ -3,7 +3,8 @@
# If we weren't given a file explicitly, we'll try to read both /etc/ssh_config
# and ~/.ssh_config in that order if they exist
if [ "$#" -eq 0 ] ; then
- for cfg in /etc/ssh_config "$HOME"/.ssh/config ; do
+ for cfg in /etc/ssh_config.d/*.conf /etc/ssh_config \
+ "$HOME"/.ssh/config.d/*.conf "$HOME"/.ssh/config ; do
[ -e "$cfg" ] || continue
set -- "$@" "$cfg"
done
diff --git a/bin/slsf.awk b/bin/slsf.awk
index 3d5c190f..87127a2c 100644
--- a/bin/slsf.awk
+++ b/bin/slsf.awk
@@ -1,9 +1,28 @@
-# Print the first non-glob "Host" name from each line of ssh_config(5) files
+# Print all the hosts from ssh_config(1) files
# Manage the processing flag (starts set in each file)
-FNR == 1 || /### sls/ { sls = 1 }
+BEGIN { sls = 1 }
+FNR { sls = 1 }
+/### sls/ { sls = 1 }
/### nosls/ { sls = 0 }
-# If processing flag set, directive is "Host", and hostname has no wildcards,
-# then print it
-sls && $1 == "Host" && $2 !~ /\*/ { print $2 }
+# Skip if we're ignoring hosts
+!sls { next }
+# Skip if this isn't a host line
+$1 != "Host" { next }
+
+# Add all the patterns after the keyword that don't have wildcards
+{
+ for (i = 2; i <= NF; i++) {
+ if ($i !~ /[?*]/) {
+ hosts[$i]++
+ }
+ }
+}
+
+# Print the complete list of hosts, sorted
+END {
+ for (host in hosts) {
+ print host | "sort"
+ }
+}
diff --git a/man/man1/sls.1df b/man/man1/sls.1df
index 83c13201..dde8e622 100644
--- a/man/man1/sls.1df
+++ b/man/man1/sls.1df
@@ -1,4 +1,4 @@
-.TH SLS 1df "May 2014" "Manual page for sls"
+.TH SLS 1df "August 2022" "Manual page for sls"
.SH NAME
.B sls
\- list the first hostname on each line of an ssh_config(5) file
@@ -10,9 +10,9 @@ ssh_config_alt1 ssh_config_alt2
.SH DESCRIPTION
.B sls
runs slsf(1df) on the given set of ssh_config(5) files to print the first
-non-wildcard hostname on each "Host" line, defaulting to /etc/ssh/ssh_config
-and ~/.ssh/config if they exist. Suitable for use in batch scripts like
-sra(1df).
+non-wildcard hostname on each "Host" line, defaulting to
+/etc/ssh/ssh_config.d/*.conf, /etc/ssh/ssh_config, ~/.ssh/config.d/*.conf, and
+~/.ssh/config if they exist. Suitable for use in batch scripts like sra(1df).
.SH SEE ALSO
slsf(1df), sra(1df), sta(1df), ssh(1), ssh_config(5)
.SH AUTHOR
diff --git a/man/man1/slsf.1df b/man/man1/slsf.1df
index 31453dca..6d59ba3d 100644
--- a/man/man1/slsf.1df
+++ b/man/man1/slsf.1df
@@ -1,4 +1,4 @@
-.TH SLSF 1df "July 2016" "Manual page for slsf"
+.TH SLSF 1df "August 2022" "Manual page for slsf"
.SH NAME
.B slsf
\- list the first hostname on each line of ssh_config(5) files
@@ -10,9 +10,9 @@ cat ~/.ssh_config |
.br
.SH DESCRIPTION
.B slsf
-iterates through the ssh_config(5) files given as its input and prints the
-first name given on each "Host" line, as long as it contains no wildcards.
-Most users will probably want the sls(1df) frontend.
+iterates through the ssh_config(5) files given as its input and prints a unique
+list of the patterns given on each "Host" line containing no wildcards. Most
+users will probably want the sls(1df) frontend instead.
.P
Within the file, a comment "### nosls" on its own line will exclude all
following output unless an "### sls" comment is read to resume it again:
diff --git a/man/man7/dotfiles.7df b/man/man7/dotfiles.7df
index 8c766c05..cae361a2 100644
--- a/man/man7/dotfiles.7df
+++ b/man/man7/dotfiles.7df
@@ -573,8 +573,8 @@ These scripts are installed by the \f[C]install-bin\f[R] target:
Three SSH-related scripts:
.RS 2
.IP \[bu] 2
-\f[C]sls(1df)\f[R] prints hostnames read from a \f[C]ssh_config(5)\f[R]
-file.
+\f[C]sls(1df)\f[R] prints hostnames read from \f[C]ssh_config(5)\f[R]
+files.
It uses \f[C]slsf(1df)\f[R] to read each one.
.IP \[bu] 2
\f[C]sra(1df)\f[R] runs a command on multiple hosts read from
diff --git a/vim/filetype.vim b/vim/filetype.vim
index 01cc0f3a..c616babd 100644
--- a/vim/filetype.vim
+++ b/vim/filetype.vim
@@ -434,18 +434,23 @@ augroup filetypedetect
\ ?*.sql
\ setfiletype sql
" OpenSSH configuration
+ "" client
autocmd BufNewFile,BufRead
- \ ssh_config,*/.ssh/config
+ \ ssh_config
+ \,*/ssh_config.d/*.conf
+ \,*/.ssh/config,
+ \,*/.ssh/config.d/*.conf
\ setfiletype sshconfig
+ "" server
+ autocmd BufNewFile,BufRead
+ \ sshd_config
+ \,*/sshd_config.d/*.conf
+ \ setfiletype sshdconfig
" sudoers(5)
autocmd BufNewFile,BufRead
\ sudoers
\,sudoers.tmp
\ setfiletype sudoers
- " OpenSSH server configuration
- autocmd BufNewFile,BufRead
- \ sshd_config
- \ setfiletype sshdconfig
" Subversion commit
autocmd BufNewFile,BufRead
\ svn-commit*.tmp