Answers:
当Shell非交互运行时,默认情况下禁用历史记录和历史记录扩展。
你需要:
#!/bin/bash
set -o history
set -o histexpand
ls /bin
ls !$
要么:
SHELLOPTS=history:histexpand bash script.sh
它会影响所有script.sh可能运行的bash实例。
bash运行script.sh,但也会影响最终可能运行的所有其他bash实例script.sh(如其他bash脚本...)。
bash运行脚本的实例。
理智的事情是
ls /bin
ls $_
要么
set ls /bin
$*
$*
要么
c='ls /bin'
$c
$c
注意事项:值得记住的是,每一个都有一些陷阱。$ _解决方案仅捕获最后一个参数:因此,ls foo bar将使$ _包含just bar。使用一个set将覆盖参数($1,$2,等)。并且所有这些文字都可以使用,但是当推广到更复杂的命令(转义和空格很重要)时,您可能会遇到一些困难。例如:(ls 'foo bar'其中单个pathname参数foo bar包含两个或多个空格,或任何其他空格字符)在以上两个示例中的任何一个中均无法正常工作。为了避免这些情况,可能需要适当的转义(可能与eval命令组合)或使用"$@"代替$*。
$_方法是不可移植的,你是对的。该set方法适用于非交互式破折号,并且${1+"$@"}(加上zsh全局别名)技巧应该是通用的,尽管我模糊地记得它set的历史不能完全移植某些(旧的)shell。eval据我所知,特别是使用适当的转义和实际命令,定义一个变量来保存命令然后进行评估的方法通常是完全可移植的。