使用反引号正确引用 tcsh 别名
Properly quoting a tcsh alias using backticks
我正在使用 tcsh。我想将“cdup”别名为 cd
到参考目录下一级目录。例如,如果我的参考目录是 /home/myself/support/bugs/,并且我在 /home/myself/support/bugs/bug1/foo/bar,我想 cdup
将目录更改为 /home/myself/support/bugs /错误1。
我尝试了以下方法:
alias cdup 'cd `perl -e \'print if $ENV{PWD} =~ m#\(/home/myself/support/bugs/[^/]+\)#\'`'
但我得到:
不匹配`.
所以根据 https://unix.stackexchange.com/questions/339328/creating-alias-for-cmd-with-backticks(感谢 brian d foy),答案是:
alias cdup 'cd `perl -e '\''print if $ENV{PWD} =~ m#(/home/wittmann/support/bugs/[^/]+)#'\''`'
这非常有效。感谢您使用 ''' 在单引号字符串中引入单引号 (') 的技巧。
有些引用是不必要的,†是什么让这变得更容易
alias cdup cd `perl -e'print if $ENV{PWD} =~ m{(/home/user/support/bugs/[^/]+)}'`
或者您可以拆分工作并避免引用问题
set d=`perl -e'print if $ENV{PWD} =~ m{(...)}'`; alias cdup $d; unset d
这两个在 tcsh
.
中做同样的事情
但是,如果 pwd
不在那个“参考目录”中,那么别名最终会变成 cd
,是什么让你回到了家目录。这就是问题的提出方式——但真的需要这样吗?
在上面的第一种方法中解决这个问题的一种方法是,如果我们在引用层次结构之外,则将目录设置为当前目录本身
alias cdup cd `perl -e'$ENV{PWD} =~ m{(...)}; print // $ENV{PWD}'`
这里//
是defined-or operator.
或者在引用层次结构之外完全避免设置别名可能更合适,但是这需要在 tcsh
中完成
set d=`perl -e'print $ENV{PWD} =~ m{(...)}'`; if ($d != "") alias cdup cd $d ; unset d
因为在正则表达式中捕获 ()
列表上下文中的匹配运算符(由 print
强加)returns 它的捕获或 undef
(如果它没有匹配),因此 shell 的变量 $d
最终要么是捕获的值,要么是一个空字符串。
然后有条件地设置别名 -- 所以 如果没有匹配,则没有 cdup
。
† 来自 tcsh manual
alias [name [wordlist]]
Without arguments, prints all aliases. With name, prints the alias for name. With name and wordlist, assigns wordlist as the alias of name. wordlist is command and filename substituted. name may not be 'alias' or 'unalias'. See also the unalias builtin command.
注意没有提到引号,wordlist
不需要引号
这是一个没有外部命令的变体:
alias cdup cd /home/myself/support/bugs/$PWD:s./home/myself/support/bugs/..:ah
它与原始行为的不同之处在于,如果在 参考目录 树之外使用,它会更改为 参考目录 ,这可能或者可能不是首选。
我正在使用 tcsh。我想将“cdup”别名为 cd
到参考目录下一级目录。例如,如果我的参考目录是 /home/myself/support/bugs/,并且我在 /home/myself/support/bugs/bug1/foo/bar,我想 cdup
将目录更改为 /home/myself/support/bugs /错误1。
我尝试了以下方法:
alias cdup 'cd `perl -e \'print if $ENV{PWD} =~ m#\(/home/myself/support/bugs/[^/]+\)#\'`'
但我得到:
不匹配`.
所以根据 https://unix.stackexchange.com/questions/339328/creating-alias-for-cmd-with-backticks(感谢 brian d foy),答案是:
alias cdup 'cd `perl -e '\''print if $ENV{PWD} =~ m#(/home/wittmann/support/bugs/[^/]+)#'\''`'
这非常有效。感谢您使用 ''' 在单引号字符串中引入单引号 (') 的技巧。
有些引用是不必要的,†是什么让这变得更容易
alias cdup cd `perl -e'print if $ENV{PWD} =~ m{(/home/user/support/bugs/[^/]+)}'`
或者您可以拆分工作并避免引用问题
set d=`perl -e'print if $ENV{PWD} =~ m{(...)}'`; alias cdup $d; unset d
这两个在 tcsh
.
但是,如果 pwd
不在那个“参考目录”中,那么别名最终会变成 cd
,是什么让你回到了家目录。这就是问题的提出方式——但真的需要这样吗?
在上面的第一种方法中解决这个问题的一种方法是,如果我们在引用层次结构之外,则将目录设置为当前目录本身
alias cdup cd `perl -e'$ENV{PWD} =~ m{(...)}; print // $ENV{PWD}'`
这里//
是defined-or operator.
或者在引用层次结构之外完全避免设置别名可能更合适,但是这需要在 tcsh
set d=`perl -e'print $ENV{PWD} =~ m{(...)}'`; if ($d != "") alias cdup cd $d ; unset d
因为在正则表达式中捕获 ()
列表上下文中的匹配运算符(由 print
强加)returns 它的捕获或 undef
(如果它没有匹配),因此 shell 的变量 $d
最终要么是捕获的值,要么是一个空字符串。
然后有条件地设置别名 -- 所以 如果没有匹配,则没有 cdup
。
† 来自 tcsh manual
alias [name [wordlist]]
Without arguments, prints all aliases. With name, prints the alias for name. With name and wordlist, assigns wordlist as the alias of name. wordlist is command and filename substituted. name may not be 'alias' or 'unalias'. See also the unalias builtin command.
注意没有提到引号,wordlist
不需要引号这是一个没有外部命令的变体:
alias cdup cd /home/myself/support/bugs/$PWD:s./home/myself/support/bugs/..:ah
它与原始行为的不同之处在于,如果在 参考目录 树之外使用,它会更改为 参考目录 ,这可能或者可能不是首选。