Fra*_*isV 6 zsh directory shell-script wildcards
我正在尝试检查目录bin
是否在有时会更改的目录中。在这种特殊情况下,ruby 的版本号可能会改变(例如$HOME/.gem/ruby/2.6.0/bin
)。这是我到目前为止所做的:
#!/usr/bin/env zsh
ruby_gem_home="$HOME/.gem/ruby/*/bin"
if [[ -d $ruby_gem_home ]]; then
echo "The ruby gems directory exists!"
else
echo "Ruby gems directory missing!"
fi
Run Code Online (Sandbox Code Playgroud)
我不想使用,find
因为这是登录过程的一部分。使用内置的 zsh/bash 命令来实现这一点的最优雅的方法是什么?
谢谢!
编辑:忘了提到这是一个zsh
脚本。
使用数组,检查数组的第一个元素(即bash中的[0],zsh中的[1])是否为目录。例如在bash
:
# the trailing slash in "$HOME"/.gem/ruby/*/bin/ ensures that
# the glob matches only directories.
rubygemdirs=( "$HOME"/.gem/ruby/*/bin/ )
if [ -d "${rubygemdirs[0]}" ] ; then
echo "At least one ruby gem dir exists"
else
echo "No ruby gem dirs were found"
fi
Run Code Online (Sandbox Code Playgroud)
要同时使用zsh
and bash
,您需要首先找出当前正在运行的 shell。这将告诉您数组的第一个索引是0
还是1
。它还将确定您是否需要(N)
与 glob一起使用以告诉 zsh 如果 glob 没有匹配项则不要退出(zsh 将在 glob 匹配错误时默认退出)。
(在这一点上,应该开始变得明显,写一个脚本在可靠的工作都bash和zsh中很可能会比它的价值更多的麻烦)
if [ -n "$BASH_VERSION" ] ; then
first_idx=0
rubygemdirs=( "$HOME"/.gem/ruby/*/bin/ )
elif [ -n "$ZSH_VERSION" ] ; then
first_idx=1
emulate sh
rubygemdirs=( "$HOME"/.gem/ruby/*/bin/ )
emulate zsh
fi
if [ -d "${rubygemdirs[$first_idx]}" ] ; then
...
Run Code Online (Sandbox Code Playgroud)
如果需要,您还可以遍历数组以检查元素是否与特定版本匹配。例如
for d in "${rubygemdirs[@]}" ; do
[[ $d =~ /2\.6\.0/ ]] && echo found gem dir for ruby 2.6.0
done
Run Code Online (Sandbox Code Playgroud)
注意:/
正则表达式中的s 是文字正斜杠。他们不会像在sed
.
我认为寻找任何目录都没有意义。使用与安装的 Ruby 版本不匹配的目录有什么意义?如果用户在 中配置了不同的目录~/.gemrc
怎么办?
我对 Ruby 不是很熟悉,但我认为正确的解决方案是在gempath
.
ruby_gem_home=$(gem environment gempath | sed 's/:.*//')
if [ -z "$ruby_gem_home" ]; then unset ruby_gem_home; fi
Run Code Online (Sandbox Code Playgroud)
function set_ruby_gem_home {
emulate -LR zsh
local dirs
dirs=($HOME/.gem/ruby/*/bin(NnOn))
if (($#dirs == 0)); then
unset ruby_gem_home
else
ruby_gem_home=$dirs[0]
fi
}
Run Code Online (Sandbox Code Playgroud)
如果没有匹配项,glob 限定符 N
确保结果是一个空数组而不是错误。glob 限定符n
并On
通过减少版本号对列表进行排序;当有多个匹配项时,调整它以选择不同的项目。
在 bash 中:
function set_ruby_gem_home {
local dirs
dirs=(~/.gem/ruby/*/bin(NnOn))
if (($#dirs == 0)); then
unset ruby_gem_home
else
ruby_gem_home=$dirs[0]
fi
}
Run Code Online (Sandbox Code Playgroud)
function set_ruby_gem_home {
local dirs restore_options
restore_options=$(setopt +o)
shopt -s nullglob
dirs=(~/.gem/ruby/*/bin)
if (($#dirs == 0)); then
unset ruby_gem_home
else
ruby_gem_home=${dirs[${#dirs[@]}-1]}
fi
eval "$restore_options"
}
Run Code Online (Sandbox Code Playgroud)
这里我取最后一个数组元素,它通常但不总是最新版本:10
在 之前排序9
。