編集2:

編集2:

私は別のスクリプトで実行可能ファイルを使用していましたが、/usr/bin/foo少し奇妙に動作していたので、同じファイル名を持つBashラッパーを作成し、/usr/local/bin/fooその中で誤った動作を修正しました。私のPATHもの/usr/local/bin:/usr/bin。ラッパースクリプトでは、無限ループに陥らないように絶対パスを介して元の実行可能ファイルを実行する必要があります。

$ cat /usr/local/bin/foo
#/bin/zsh
/usr/bin/foo | grep -v "^INFO" # reduce output

foonext inを実行する簡単な方法(おそらくZshまたはBash固有)はありますかPATH?つまり、 current が実行されるディレクトリの次のディレクトリでfoo元の実行ファイルの絶対パスを使用する必要はありませんか?PATHfoo

私はそれのための関数を作ることができます/etc/zshenv。あまりありません。もし基準があるのか​​知りたいです。エイリアスを使用したり、元の実行可能ファイルを回復したくありません。


編集 1: = $ cat /usr/local/bin/foo #/bin/zsh path=(${path/#%$0:A:h}) foo | grep -v "^INFO" # 出力を減らす

これにより、現在の実行可能ファイル()の絶対()ディレクトリ()と正確に一致する()PATH()の${path/...}すべての文字列が消去されます(ただし保存されます)。正直言って、StackExchangeで組み立てましたが、完全には理解していませんでした。私はそれが私を噛まないことを願っています。#%:A:h$0

編集2:

$ cat /usr/local/bin/foo
#/bin/zsh
path[${path[(i)$0:A:h]}]=() foo | grep -v "^INFO" # reduce output

$path[(i)foo]foo配列のインデックスを検索するpathか、1に配列長を加えた値を見つけます。

答え1

スクリプトがあるディレクトリ($0:hzsh、"${0%/*}"in sh)を見つけて、そのディレクトリから削除できますPATHpath=(${path:#$0:h})zsh、shでもっと複雑。同じディレクトリが2回含まれている場合PATH(たとえば、シンボリックリンクを介して)、この操作は失敗する可能性があります。

直接アプローチの欠点は、パスからディレクトリが削除されるが、同じディレクトリにある他のプログラムが理想的である可能性があることです。パスの検索に変更されたパスのみを使用すると、この問題を解決できます。

next=$(path=(${path:#$0:h}); print -lr -- =$0:t)
$next

代わりにPATH手動で照会を実行し、実行中のスクリプトをスキップします。

for d in $path; do
  if [[ -x $d/$0:t && ! $d/$0:t -ef $0 ]]; then
    exec $d/$0:t
  fi
done

答え2

例:カスタムエイリアスと実際のコマンドを印刷するには、
$ HOME / bin /に別のコマンドを追加すると、順番にエイリアスが表示され、その後にPATH付きのエントリが表示されます。同じ順序。type -a egrepegrepegrep

$CD#家に帰る

$mkdir -p 空

$PATH=$HOME/bin:$PATH

$type-a egrep
egrepのエイリアスは `egrep --color = auto'です。
egrep は /bin/egrep です。

$ echo -e >bin/egrep '#!/bin/bash\necho TEST'

$ chmod 755 bin/egrep

$type-a egrep
egrepのエイリアスは `egrep --color = auto'です。
egrepは/home/$USER/bin/egrepです。
egrep は /bin/egrep です。

# /home になくエイリアスでもない唯一の項目だと確信していると仮定
$タイプ-a egrep | grep -Ev '/home|alias' |cut -d''-f3
/bin/egrep

$rm $HOME/bin/egrep

答え3

次のことができます。

#! /bin/zsh -

# find the other occurrences of a command with the same name in $path that
# are a different file
other_mes=(
  ${^path/#%/.}/$0:t(N*^e['[[ $REPLY -ef $0 ]]'])
)

if (( ! $#other_mes )) {
  print -ru2 Could not find any other $0:t in PATH.
  exit 1
}

# run the first found
$other_mes[1] "$@" | grep -v '^INFO'

# return the exit status of the other me, not of grep
exit $pipestatus[1]
  • ${path/#%/.}$path空の要素を次に置き換えます。.
  • $0:t:尾(基本名)$0
  • [[ a -ef b ]]abとが同じファイルへの2つのパスであるため、シンボリックリンクの確認後に同じファイルであることが確認された場合はtrueを返します(たとえば、またはへのシンボリックリンク、または互いへのハードリンクまたはシンボリックリンクのためvs /usr/bin/foo)。/bin/foo/bin/usr/bin../bin/foo$PWD/usr/local/usr/foo/../bin/foo

sh構文(および最もサポートされている実装)を使用し[て改行文字で終わらないと仮定すると、次のようになります。-ef$0

#! /bin/sh -
other_me=$(
  me=$(dirname -- "$0")
  IFS=:; set -o noglob
  for dir in $PATH''; do
    other_me=${dir:-.}/$me
    if [ -x "$other_me" ] && [ -f "$other_me" ] && [ ! "$other_me" -ef "$me" ]; then
      printf '%s\n' "$other_me"
      exit
    fi
  done
  printf>&2 '%s\n' "Cound not find any other $me in PATH."
  exit 1
) || exit

{
  exit_status=$(
    {
      {
        "$other_me" "$@" 4>&-
        echo "$?" >&4 4>&-
      } 3>&- | grep -v '^INFO' >&3 3>&- 4>&-
    } 4>&1
  )
} 3>&1
exit "$exit_status"

末尾の複合ビットによって取得された終了状態です$other_me

関連情報