Fish:如果使用 sed 编辑 $PATH,则从 $PATH 中删除路径失败
Fish: remove path from $PATH fails if $PATH edited with sed
我正在使用 fish
2.2.0。 (是的,我知道它很旧,我对此无能为力。)
我想从 $PATH 中取消设置路径 (/usr/local/ferret-6.82/bin
)。为此,我假设使用 sed
会起作用:
> echo $PATH
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /usr/local/ferret-6.82/bin /opt/intel/bin
> echo $PATH | sed -e 's:/usr/local/ferret-6.82/bin ::g'
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /opt/intel/bin
太棒了!然而...
> set -gx PATH (echo $PATH | sed -e 's:/usr/local/ferret-6.82/bin ::g')
set: Warning: path component /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /opt/intel/bin may not be valid in PATH.
set: No such file or directory
> echo $PATH
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /usr/local/ferret-6.82/bin /opt/intel/bin
当然所有这些目录都存在。手动设置路径有效:
> set -gx PATH /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /opt/intel/bin
> echo $PATH
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /opt/intel/bin
这里有什么问题?为什么我的 sed
路径设置失败?
$PATH、$CDPATH 和$MANPATH 在鱼中比较特殊。 (从2.2.0开始,就是那些特定的变量。在此之前,这将适用于任何变量)
它们是每个组件一个元素的列表,在向外部程序导出和从外部程序导入时,这些列表会转换为通常的冒号分隔形式。
你在这里要做的是使用 fish-script:
if set -l ind (contains -i -- /usr/local/ferret-6.82/bin $PATH)
set -e PATH[$ind]
end
contains -i
将 return 0 并输出第一个参数所在的索引,set -e
将从列表中删除该元素。 “--”是选项分隔符,之后没有参数将被解释为选项。请注意 $PATH
缺少引号,这将导致 $PATH 的每个组件作为单独的参数传递。
或者,由于 fish 在换行符上拆分命令替换,您可以每行对 $PATH 进行操作,
printf '%s\n' $PATH | sed '\_/usr/local/ferret-6.82/bin_d'
(注意:对于 "d" 命令,有必要转义分隔符 - 在本例中为“_” - 如果不是“/”,则首次使用时)
我正在使用 fish
2.2.0。 (是的,我知道它很旧,我对此无能为力。)
我想从 $PATH 中取消设置路径 (/usr/local/ferret-6.82/bin
)。为此,我假设使用 sed
会起作用:
> echo $PATH
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /usr/local/ferret-6.82/bin /opt/intel/bin
> echo $PATH | sed -e 's:/usr/local/ferret-6.82/bin ::g'
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /opt/intel/bin
太棒了!然而...
> set -gx PATH (echo $PATH | sed -e 's:/usr/local/ferret-6.82/bin ::g')
set: Warning: path component /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /opt/intel/bin may not be valid in PATH.
set: No such file or directory
> echo $PATH
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /usr/local/ferret-6.82/bin /opt/intel/bin
当然所有这些目录都存在。手动设置路径有效:
> set -gx PATH /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /opt/intel/bin
> echo $PATH
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games /opt/intel/bin
这里有什么问题?为什么我的 sed
路径设置失败?
$PATH、$CDPATH 和$MANPATH 在鱼中比较特殊。 (从2.2.0开始,就是那些特定的变量。在此之前,这将适用于任何变量)
它们是每个组件一个元素的列表,在向外部程序导出和从外部程序导入时,这些列表会转换为通常的冒号分隔形式。
你在这里要做的是使用 fish-script:
if set -l ind (contains -i -- /usr/local/ferret-6.82/bin $PATH)
set -e PATH[$ind]
end
contains -i
将 return 0 并输出第一个参数所在的索引,set -e
将从列表中删除该元素。 “--”是选项分隔符,之后没有参数将被解释为选项。请注意 $PATH
缺少引号,这将导致 $PATH 的每个组件作为单独的参数传递。
或者,由于 fish 在换行符上拆分命令替换,您可以每行对 $PATH 进行操作,
printf '%s\n' $PATH | sed '\_/usr/local/ferret-6.82/bin_d'
(注意:对于 "d" 命令,有必要转义分隔符 - 在本例中为“_” - 如果不是“/”,则首次使用时)