スクリプトで!$を使用できませんか?


11

なぜこれが機能しないのかと思っているだけ

#!/bin/bash 

ls /bin
ls !$

ls /bin2回実行する予定ですが、2番目!$は解釈されなかったためエラーが発生します

私は何かを逃したのですか、それとも!$コマンドラインでのみ機能しましたか?

man bash(Mac)で関連するパーツが見つかりませんでした


9
解決策はありますが、これはスクリプトでこれを実現するための本当に最良の方法ですか?対話型ではない理由で、履歴はデフォルトで無効になっています-長いスクリプトは.bash_historyファイルをスパムします。これを質問する価値はなかったと言っているわけではありませんが、これをスクリプトで使用することを考えている場合、これは本当に最善の方法ですか?
flungo 2016

回答:


26

シェルが非対話的に実行される場合、履歴履歴拡張はデフォルトで無効になっています。

必要なもの:

#!/bin/bash 

set -o history
set -o histexpand

ls /bin
ls !$

または:

SHELLOPTS=history:histexpand bash script.sh

実行される可能性のあるすべてのbashインスタンスに影響しますscript.sh


9
SHELLOPTSを使用する場合は注意が必要です。これは、bashその実行script.shに影響しbashますscript.shが、最終的に実行される可能性のある他のすべてのインスタンスにも影響します(他のbashスクリプトのように...)。
ステファンChazelas

また、スクリプトを実行する他のインスタンスに影響しません。 bash
Blacklight Shining

@StéphaneChazelasのコメントを編集すると、この回答は改善されると思います。
Oliphaunt-2016年

7

正気なことは

ls /bin
ls $_

または

set ls /bin
$*
$*

または

c='ls /bin'
$c
$c

警告:これらのそれぞれにいくつかの落とし穴があることを覚えておく価値があります。$ _ソリューションは最後の単一の引数のみをキャプチャします。そのためls foo bar、$ _にはだけが含まれますbar。使用して1 set(引数を上書きする$1$2など)。記述されているとおりにこれらすべてが機能しますが、より複雑なコマンド(エスケープと空白が重要な場合)に一般化すると、いくつかの問題が発生する可能性があります。例:(ls 'foo bar'単一のパス名引数foo bar2つ以上のスペース、またはその他の空白文字が含まれている場合)は、これらの例のどちらでも正しく動作しません。これらのケースを回避するには、適切なエスケープ(evalコマンドと組み合わせる場合があります)、またはの"$@"代わりに使用$*することが必要になる場合があります。


1
+1は、移植性があり、インタラクティブな使用を容易にすることを目的としたバシズムを乱用しません。(余談ですが、デフォルト設定で感嘆符をインタラクティブに拡張したいというbashの欲求は、他のシェルのユーザーとしては直感に反するものであり、複雑なシェルコマンドを実行しようとすると常に邪魔になるため、逆効果です)。
mtraceur 2016

この時点で書かれているように、初心者のシェルスクリプターがより複雑なコマンドに一般化しようとするときに問題になる可能性があるため、+ 1を与えることをためらっていました。私は、起こり得る落とし穴を説明する警告パラグラフを少なくとも追加するように編集を提案しました。
mtraceur 2016

@mtraceur:移植性はなく、bash、zsh、kshでのみ機能します(2つのコマンドが同じ行にない場合)。インタラクティブな場合のみダッシュ、mkshで作業する
cuonglm

@cuongim:申し訳ありませんが、私は多分あまりにも不用意に一般的でした。$_方法は、あなたが正しい、移植性がありません。このsetアプローチは非インタラクティブダッシュで機能し、${1+"$@"}(プラスzshグローバルエイリアス)トリックは一般的ですsetが、一部の(古い?)シェルでは完全に移植できないという歴史があることを漠然と覚えています。特に適切なエスケープと実際のevalコマンドを使用する、変数を保持してコマンドを定義してから評価するというアプローチは、私が知る限り、完全に移植可能です。
mtraceur 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.