fix: parse SSH config entries with tabs as well as spaces
resolve_ssh_alias() now extracts tokens with 'read -r', which
collapses tabs and spaces uniformly. Two bugs were at play:
1. The previous parser split on literal spaces
(key="${line%% *}") and used '${line#Host }' to drop the
Host directive, so configs that used tab indentation
(e.g. '\tHostName 10.60.16.35') ended up with key being the
whole line and never matching the case branches. Result:
'has no HostName in ~/.ssh/config' even when one was present.
2. The script's global IFS is $'\n\t' (no space), which made
'read' unable to split on spaces at all. Fixed by restoring
space-aware IFS locally inside the loop.
Verified against tabbed, spaced, mixed, indented-comment and
Host\tname configs; behavior with the original space-separated
configs is unchanged.
This commit is contained in:
+17
-12
@@ -130,15 +130,19 @@ resolve_ssh_alias() {
|
||||
[[ -f "$config" ]] \
|
||||
|| die "Cannot resolve '$alias': $config not found and value has no '@'."
|
||||
|
||||
local in_block=0 hostname="" user="" port="" identity="" line key value p
|
||||
local in_block=0 hostname="" user="" port="" identity="" line first p
|
||||
local -a patterns
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
line="${line#"${line%%[![:space:]]*}"}"
|
||||
[[ -z "$line" || "${line:0:1}" == "#" ]] && continue
|
||||
key="${line%% *}"
|
||||
if [[ "$key" == "Host" ]]; then
|
||||
# Force whitespace-aware splitting (the script's global IFS excludes spaces).
|
||||
local IFS=$' \t\n'
|
||||
while read -r line || [[ -n "$line" ]]; do
|
||||
# First whitespace-separated token (tabs and spaces collapse uniformly).
|
||||
read -r first _ <<< "$line"
|
||||
[[ -z "$first" || "$first" == "#" ]] && continue
|
||||
|
||||
if [[ "$first" == "Host" ]]; then
|
||||
if (( in_block )); then break; fi
|
||||
read -r -a patterns <<< "${line#Host }"
|
||||
read -r -a patterns <<< "$line"
|
||||
patterns=("${patterns[@]:1}")
|
||||
in_block=0
|
||||
for p in "${patterns[@]}"; do
|
||||
if [[ "$p" == "$alias" ]]; then
|
||||
@@ -149,12 +153,13 @@ resolve_ssh_alias() {
|
||||
done
|
||||
continue
|
||||
fi
|
||||
|
||||
if (( in_block )); then
|
||||
case "$key" in
|
||||
HostName) hostname="${line#* }" ;;
|
||||
User) user="${line#* }" ;;
|
||||
Port) port="${line#* }" ;;
|
||||
IdentityFile) identity="${line#* }" ;;
|
||||
case "$first" in
|
||||
HostName) read -r _ hostname <<< "$line" ;;
|
||||
User) read -r _ user <<< "$line" ;;
|
||||
Port) read -r _ port <<< "$line" ;;
|
||||
IdentityFile) read -r _ identity <<< "$line" ;;
|
||||
esac
|
||||
fi
|
||||
done < "$config"
|
||||
|
||||
Reference in New Issue
Block a user