タスクの1つが実行されているディレクトリにディレクトリをすばやく変更する方法はありますか?

タスクの1つが実行されているディレクトリにディレクトリをすばやく変更する方法はありますか?

出力はjobs次のとおりです

[1]   Stopped                 TERM=xterm-256color vim --servername vim ~/.gitconfig
[2]-  Stopped                 TERM=xterm-256color vim --servername vim ~/.vimrc  (wd: ~)
[3]+  Stopped                 TERM=xterm-256color vim --servername vim i3blocks.conf  (wd: ~/.config/i3/configs)

セクション(ある場合)が表示される場所(wd: path)pathそのジョブが実行されるディレクトリ。

私はそのディレクトリに行き、その仕事の1つを行うことについて何度も考えました。

これを行うユーティリティがありますか?

答え1

では、連想配列はジョブzsh番号$jobdirsをそのジョブが開始された作業ディレクトリーにマップするため、ジョブnのディレクトリーcd $jobdirs[n]に移動できます(ジョブが存在しない場合は家に戻るのではなくエラーが発生します)。cdcd ${jobdirs[n]?}

~$ jobs -d
[1]  - running    sleep 1000
(pwd : /tmp)
[2]  + suspended  sleep 123123
(pwd : /usr/local)
~$ cd $jobdirs[2]
/usr/local$

また、各タスクのステータスとコードの連想配列も参照$jobstatesしてください。$jobtexts

bash唯一のオプションはタスクの出力を解析することですが、残念ながら経験的な方法でのみ実行できます。たとえば、次を参照してください。

bash-5.1$ mkdir ') (wd: blah blah)
[5] (wd: blah blih)
'
bash-5.1$ cd ') (wd: blah blah)
[5] (wd: blah blih)
'
bash-5.1$ sh -c 'sleep inf' '(wd: /etc)
[2] (wd: bloh bloh)
'
^Z
[1]+  Stopped                 sh -c 'sleep inf' '(wd: /etc)
[2] (wd: bloh bloh)
'
bash-5.1$ jobs 1
[1]+  Stopped                 sh -c 'sleep inf' '(wd: /etc)
[2] (wd: bloh bloh)
'
bash-5.1$ cd /
bash-5.1$ jobs 1
[1]+  Stopped                 sh -c 'sleep inf' '(wd: /etc)
[2] (wd: bloh bloh)
'  (wd: ~/1/) (wd: blah blah)
[5] (wd: blah blih)
)

(wd:...)ジョブディレクトリが現在のジョブディレクトリでない場合にのみ印刷されること、およびジョブのコマンドラインまたはジョブディレクトリにsが含まれている場合、どのsが実際のジョブディレクトリの開始かを(wd: ...) 知る方法がないことがわかります。(wd:

また、ホームディレクトリを~

また、wd:ローカライズされています。たとえば、ウクライナ語では次のようになります。

bash-5.1$ LC_ALL=uk_UA.utf8 jobs 1
[1]+  Зупинено        sh -c 'sleep inf' '(wd: /etc)
[2] (wd: bloh bloh)
'  (РД: ~/1/) (wd: blah blah)
[5] (wd: blah blih)
)

jobsしたがって、期待する対応するロケールから呼び出す必要があります。タスクリスト略語。

あなたができることは、経験的な方法を使用して最善を尽くすことです。

cdj() {
  local dir
  dir=$(LC_ALL=C jobs -- "$1") || return
  case $dir in
    (*'(wd:'*')')
      dir=${dir%')'}
      dir=${dir##*'(wd: '}
      case $dir in
        ('~'*) dir=$HOME${dir#'~'}
      esac
      printf >&2 '%s\n' "Job $1's dir is likely \"$dir\""
      cd -- "$dir";;
    (*)
      printf >&2 '%s\n' "Job $1's dir is likely the current directory already"
  esac
}

上記で設計した例では失敗しましたが、ほとんどの一般的な状況では機能します。

答え2

これで、次の関数を定義する問題を解決しました~/.bashrc

cdj () {
  jobNumber="$1"
  dir="$(jobs | grep "^\[$jobNumber\]" | sed 's/.*(wd: \(.*\))/\1/;t;d')"
  [[ -n "$dir" ]] && eval "cd $dir"
}

これにより、存在しないタスクまたは現在のディレクトリで実行されているタスクの数を渡す場合、これを実行して(意図的に)失敗する可能性があります。cd job-number

関連情報