我曾经使用CShell(csh),它允许您创建一个接受参数的别名。符号有点像
alias junk="mv \\!* ~/.Trash"
在巴什,这似乎行不通。鉴于Bash有许多有用的特性,我会假设这一特性已经实现,但我想知道如何实现。
我曾经使用CShell(csh),它允许您创建一个接受参数的别名。符号有点像
alias junk="mv \\!* ~/.Trash"
在巴什,这似乎行不通。鉴于Bash有许多有用的特性,我会假设这一特性已经实现,但我想知道如何实现。
当前回答
这是另一种使用read的方法。我使用这个方法通过名称片段对文件进行暴力搜索,忽略了“拒绝权限”消息。
alias loc0='( IFS= read -r x; find . -iname "*" -print 2>/dev/null | grep $x;) <<<'
一个简单的例子:
$ ( IFS= read -r x; echo "1 $x 2 ";) <<< "a b"
1 a b 2
注意,这将参数作为字符串转换为变量。可以在引号中使用多个参数,以空格分隔:
$ ( read -r x0 x1; echo "1 ${x0} 2 ${x1} 3 ";) <<< "a b"
1 a 2 b 3
其他回答
要具体回答有关创建别名以将文件移动到垃圾箱文件夹而不是删除文件的问题,请执行以下操作:
alias rm="mv "$1" -t ~/.Trash/"
当然,你必须先创建dir~/.Trash。
然后只需发出以下命令:
$rm <filename>
$rm <dirname>
函数和别名都可以使用其他函数和别名所示的参数。此外,我想指出几个其他方面:
1.函数在自己的作用域中运行,别名共享作用域
在需要隐藏或暴露某些内容的情况下,了解这种差异可能很有用。它还表明,函数是封装的更好选择。
function tfunc(){
GlobalFromFunc="Global From Func" # Function set global variable by default
local FromFunc="onetwothree from func" # Set a local variable
}
alias talias='local LocalFromAlias="Local from Alias"; GlobalFromAlias="Global From Alias" # Cant hide a variable with local here '
# Test variables set by tfunc
tfunc # call tfunc
echo $GlobalFromFunc # This is visible
echo $LocalFromFunc # This is not visible
# Test variables set by talias
# call talias
talias
echo $GlobalFromAlias # This is invisible
echo $LocalFromAlias # This variable is unset and unusable
输出:
bash-3.2$ # Test variables set by tfunc
bash-3.2$ tfunc # call tfunc
bash-3.2$ echo $GlobalFromFunc # This is visible
Global From Func
bash-3.2$ echo $LocalFromFunc # This is not visible
bash-3.2$ # Test variables set by talias
bash-3.2$ # call talias
bash-3.2$ talias
bash: local: can only be used in a function
bash-3.2$ echo $GlobalFromAlias # This is invisible
Global From Alias
bash-3.2$ echo $LocalFromAlias # This variable is unset and unusable
2.包装脚本是更好的选择
在我身上发生过几次,当通过ssh登录或涉及切换用户名或多用户环境时,找不到别名或函数。源点文件有一些提示和技巧,或者这个有趣的别名:aliassd='sudo'让这个后续的别名aliasinstall='sd-apt-get-install'按预期工作(注意sd='udo'中的额外空间)。然而,在这种情况下,包装脚本比函数或别名更有效。包装器脚本的主要优点是它在预期路径(即/usr/loca/bin/)下是可见的/可执行的,其中作为函数/别名需要在其可用之前获取。例如,您将一个函数放在~/.bash_profile或~/.bahrc中用于bash,但稍后切换到另一个shell(即zsh),则该函数不再可见。因此,当您有疑问时,包装脚本始终是最可靠和可移植的解决方案。
注意:如果这个想法不明显,除了别名之外,使用别名是一个坏主意,第一个是“别名中的函数”,第二个是“难以读取的重定向/源”。此外,还有一些缺陷(我认为这是显而易见的,但以防万一你会感到困惑:我并不是说它们真的可以在任何地方使用!)
我以前回答过这个问题,过去总是这样:
alias foo='__foo() { unset -f $0; echo "arg1 for foo=$1"; }; __foo()'
这是很好的,除非你避免一起使用函数。在这种情况下,您可以利用bash强大的重定向文本的能力:
alias bar='cat <<< '\''echo arg1 for bar=$1'\'' | source /dev/stdin'
它们的长度大致相同,只需几个字符即可。
真正的关键是时间差,顶部是“函数方法”,底部是“重定向源”方法。为了证明这一理论,时机不言自明:
arg1 for foo=FOOVALUE
real 0m0.011s user 0m0.004s sys 0m0.008s # <--time spent in foo
real 0m0.000s user 0m0.000s sys 0m0.000s # <--time spent in bar
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.010s user 0m0.004s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.011s user 0m0.000s sys 0m0.012s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.012s user 0m0.004s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.010s user 0m0.008s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
这是随机间隔进行的约200个结果的底部。函数创建/销毁似乎比重定向花费更多的时间。希望这将有助于未来的访问者解决这个问题(我不想对自己保密)。
Bash别名不直接接受参数。您必须创建一个函数。
alias不接受参数,但可以像别名一样调用函数。例如:
myfunction() {
#do things with parameters like $1 such as
mv "$1" "$1.bak"
cp "$2" "$1"
}
myfunction old.conf new.conf #calls `myfunction`
顺便说一句,.bashrc和其他文件中定义的Bash函数可以作为shell中的命令使用。例如,您可以这样调用前面的函数
$ myfunction original.conf my.conf
alias junk="delay-arguments mv _ ~/.Trash"
延迟参数脚本:
#!/bin/bash
# Example:
# > delay-arguments echo 1 _ 3 4 2
# 1 2 3 4
# > delay-arguments echo "| o n e" _ "| t h r e e" "| f o u r" "| t w o"
# | o n e | t w o | t h r e e | f o u r
RAW_ARGS=("$@")
ARGS=()
ARG_DELAY_MARKER="_"
SKIPPED_ARGS=0
SKIPPED_ARG_NUM=0
RAW_ARGS_COUNT="$#"
for ARG in "$@"; do
#echo $ARG
if [[ "$ARG" == "$ARG_DELAY_MARKER" ]]; then
SKIPPED_ARGS=$((SKIPPED_ARGS+1))
fi
done
for ((I=0; I<$RAW_ARGS_COUNT-$SKIPPED_ARGS; I++)); do
ARG="${RAW_ARGS[$I]}"
if [[ "$ARG" == "$ARG_DELAY_MARKER" ]]; then
MOVE_SOURCE_ARG_NUM=$(($RAW_ARGS_COUNT-$SKIPPED_ARGS+$SKIPPED_ARG_NUM))
MOVING_ARG="${RAW_ARGS[$MOVE_SOURCE_ARG_NUM]}"
if [[ "$MOVING_ARG" == "$ARG_DELAY_MARKER" ]]; then
echo "Error: Not enough arguments!"
exit 1;
fi
#echo "Moving arg: $MOVING_ARG"
ARGS+=("$MOVING_ARG")
SKIPPED_ARG_NUM=$(($SKIPPED_ARG_NUM+1))
else
ARGS+=("$ARG")
fi
done
#for ARG in "${ARGS[@]}"; do
#echo "ARGN: $ARG"
#done
#echo "RAW_ARGS_COUNT: $RAW_ARGS_COUNT"
#echo "SKIPPED_ARGS: $SKIPPED_ARGS"
#echo "${ARGS[@]}"
QUOTED_ARGS=$(printf ' %q' "${ARGS[@]}")
eval "${QUOTED_ARGS[@]}"