2016-09-28 41 views
1

删除我的PATH环境变量特定变量给定一个输入变量说usr/bin下以下路径我如何使用鱼贝

echo $PATH 
/usr/local/bin /usr/bin /bin /usr/sbin /sbin /usr/local/sbin /Developer/bin 

我该怎么写(鱼外壳)给定一个函数字符串/输入可以从我的PATH变量中删除该路径? - >理想的情况是删除第一次出现(VS一个删除此类变量的所有实例)

我正在考虑写一个小功能,如

deleteFromPath usr/bin 

它会更好在写这篇脚本语言像Perl/python/ruby​​而不是鱼壳?

for x in $list 
    if [ $x = $argv ] 
     //delete element x from list -> How? 
    end 
end 
+0

是否有一个原因,你跳转到perl/python/ruby​​而不是,比如说,一个POSIX shell? –

+0

'IFS =:read -r -a path_entries <<<“$ PATH”;为“$ {!path_entries [@]}”中的idx;为arg做; do [[$ {path_entries [$ idx]} =“$ arg”]] && unset path_entries [$ idx];完成;完成; printf -v PATH'%s:'“$ {path_entries [@]}”; PATH = $ {PATH%':'}'让我觉得它是一个相当理智的bash实现,对正确性持谨慎态度。鱼确实不是为脚本编写的;它是一个* interactive * shell。 –

+0

@CharlesDuffy:'fish'不支持'POSIX'子串删除技术? – Inian

回答

4

这是相当容易的鱼做的。

使用set -e,您不仅可以擦除整个变量,还可以清除列表中的元素,例如set -e PATH[2]以删除第二个元素(鱼的计数列表索引从1开始)。

随着contains -i,你可以找到一个元素所在的索引。

所以你想打电话给set -e PATH[(contains -i $argv $PATH)]

随着一些错误处理和edgecases固定,this'd样子

function deleteFromPath 
    # This only uses the first argument 
    # if you want more, use a for-loop 
    # Or you might want to error `if set -q argv[2]` 
    # The "--" here is to protect from arguments or $PATH components that start with "-" 
    set -l index (contains -i -- $argv[1] $PATH) 
    # If the contains call fails, it returns nothing, so $index will have no elements 
    # (all variables in fish are lists) 
    if set -q index[1] 
     set -e PATH[$index] 
    else 
     return 1 
    end 
    end 

注意,这比较路径,所以你需要调用deleteFromPath /usr/bin,与领先的“/” 。否则它不会找到组件。

+0

谢谢,这是超级信息。 –

-1

我们可以调用bash。 :)

function removePathElements 
    set PATH (bash -c 'IFS=: read -r -a path_entries <<<"$PATH"; for idx in "${!path_entries[@]}"; do for arg; do [[ ${path_entries[$idx]} = "$arg" ]] && unset path_entries[$idx]; done; done; printf "%s\n" "${path_entries[@]}"' _ $argv) 
end 

需要明确的是,嵌入式的bash代码在这里是:

IFS=: read -r -a path_entries <<<"$PATH" 
for idx in "${!path_entries[@]}"; do 
    for arg; do 
    [[ ${path_entries[$idx]} = "$arg" ]] && unset path_entries[$idx] 
    done 
done 
printf "%s\n" "${path_entries[@]}" 
+0

要清楚 - 这绝对不是一个很好的答案,并且鱼原生接受的答案*值得*被接受并有我的赞赏。另一方面,AFAICT对此没有任何错误*,这就是为什么我要离开它(并且会赞赏一个解释,而不是一个纯粹的downvote,如果实际上*是尊重它是不正确,而不仅仅是冗长和低效)。 –