Hello All, It may not directly be related to zsh but please help me improve my code. There is following function definition in my .zshrc. ---------------------------------------------------------------------- 01: update_ssh_auth_sock () { 02: if [ -z "${TMUX}" ] 03: then 04: echo "This function must be called inside tmux session." 05: return -1 06: fi 07: newval=$(tmux show-environment SSH_AUTH_SOCK | sed -n 's/^SSH_AUTH_SOCK=\(.*\)/\1/p') 08: if [ -n "${SSH_AUTH_SOCK}" ] 09: then 10: if [ -z "${newval}" ] 11: then 12: unset SSH_AUTH_SOCK 13: echo "SSH_AUTH_SOCK is cleared." 14: elif [ "${SSH_AUTH_SOCK}" != "${newval}" ] 15: then 16: export SSH_AUTH_SOCK=${newval} 17: echo "SSH_AUTH_SOCK is updated." 18: else 19: echo "SSH_AUTH_SOCK is unchanged." 20: fi 21: elif [ -n "${newval}" ] 22: then 23: export SSH_AUTH_SOCK=${newval} 24: echo "SSH_AUTH_SOCK is set now." 25: else 26: echo "SSH_AUTH_SOCK stays unset." 27: fi 28: return 0 29: } ---------------------------------------------------------------------- I use this function to update environment variables related to ssh-agent when I attaches tmux session that already exists before login. Currently this function only update SSH_AUTH_SOCK but I would like to change it so it also updates SSH_AGENT_PID. The easiest way is to copy lines from 7 to 27, paste them after line 27 and replace SSH_AUTH_SOCK with SSH_AGENT_PID. But if possible I would like to avoid duplication of code. At first following 2 idea hit upon me. 1. Define function that updates single environment variable and pass variable name as argument of it. 2. Use 'for name in word; do list done' such as following. for valname in SSH_AUTH_SOCK SSH_AGENT_PID do (update value of environment variable named ${valname}) done But it seems that both require nested variable expansion and that it is impossible. Then is there any other way to avoid code duplication? Best Regards. --- Yasuhiro KIMURA
> 2020/05/25 18:02, Yasuhiro KIMURA <yasu@utahime.org> wrote:
>
> 1. Define function that updates single environment variable and pass
> variable name as argument of it.
> 2. Use 'for name in word; do list done' such as following.
>
> for valname in SSH_AUTH_SOCK SSH_AGENT_PID
> do
> (update value of environment variable named ${valname})
> done
>
> But it seems that both require nested variable expansion and that it
> is impossible. Then is there any other way to avoid code duplication?
Suppose a parameter, say valname, contains a name of another parameter;
valname=SSH_AUTH_SOCK
Then you can GET the current value of SSH_AUTH_SOCK by
if [[ -n ${(P)valname} ]]; then ...
You can SET a new value to SSH_AUTH_SOCK in a couple of ways.
In your case, probably
export $valname='new value'
would be the simplest. If you don't want to export the variable, then,
: ${(P)valname::=new value}
Hello Jun,
Thank you for reply.
From: "Jun. T" <takimoto-j@kba.biglobe.ne.jp>
Subject: Re: Avoid duplication of code
Date: Mon, 25 May 2020 23:22:39 +0900
> Suppose a parameter, say valname, contains a name of another parameter;
>
> valname=SSH_AUTH_SOCK
>
> Then you can GET the current value of SSH_AUTH_SOCK by
>
> if [[ -n ${(P)valname} ]]; then ...
>
> You can SET a new value to SSH_AUTH_SOCK in a couple of ways.
> In your case, probably
>
> export $valname='new value'
>
> would be the simplest. If you don't want to export the variable, then,
>
> : ${(P)valname::=new value}
I changed function definition as following.
----------------------------------------------------------------------
update_tmux_ssh_agent_environments () {
if [ -z "${TMUX}" ]
then
echo "This function must be called inside tmux session."
return -1
fi
for varname in SSH_AGENT_PID SSH_AUTH_SOCK
do
newvalue=$(tmux show-environment "${varname}" | sed -n "s/^${varname}=\(.*\)/\1/p")
if [ -n "${(P)varname}" ]
then
if [ -z "${newvalue}" ]
then
unset "${varname}"
echo "${varname} is cleared."
elif [ "${(P)varname}" != "${newvalue}" ]
then
export "${varname}"="${newvalue}"
echo "${varname} is updated."
else
echo "${varname} is unchanged."
fi
elif [ -n "${newvalue}" ]
then
export "${varname}"="${newvalue}"
echo "${varname} is set now."
else
echo "${varname} stays unset."
fi
done
return 0
}
----------------------------------------------------------------------
And now I can successfully update both SSH_AGENT_PID and
SSH_AUTH_SOCK.
---
Yasuhiro KIMURA
Yasuhiro KIMURA wrote on Thu, 28 May 2020 17:05 +0900: > ---------------------------------------------------------------------- > update_tmux_ssh_agent_environments () { > if [ -z "${TMUX}" ] > then > echo "This function must be called inside tmux session." > return -1 > fi You might want to add «local varname» here. > for varname in SSH_AGENT_PID SSH_AUTH_SOCK > } > ---------------------------------------------------------------------- Cheers, Daniel
From: Daniel Shahaf <d.s@daniel.shahaf.name>
Subject: Re: Avoid duplication of code
Date: Thu, 28 May 2020 08:53:18 +0000
>> ----------------------------------------------------------------------
>> update_tmux_ssh_agent_environments () {
>> if [ -z "${TMUX}" ]
>> then
>> echo "This function must be called inside tmux session."
>> return -1
>> fi
>
> You might want to add «local varname» here.
>
>> for varname in SSH_AGENT_PID SSH_AUTH_SOCK
>> }
>> ----------------------------------------------------------------------
>
> Cheers,
Thank you for pointing out. I added 'local newvalue varname' at the
top of function definition.
---
Yasuhiro KIMURA