71532
以下のようなシェルスクリプトtest.shがあります。

```

    #!/bin/bash
    for i in $(seq 10);
    do
      echo "i=$i"
      sleep 1
    done
    
```

それを以下のように実行した場合、 `kill $P1` でプロセス./test.shは直ちに終了します。

```

    #!/bin/bash
    ./test.sh &
    P1=$!
    sleep 3
    kill $P1
    echo "end"
    
```

```

    i=1
    i=2
    i=3
    end
    
```

ただし./test.shのあとに&&で後続コマンドを設定した場合、./test.shは `kill $P1` で終了しません。

```

    #!/bin/bash
    ./test.sh && echo "yes" &
    P1=$!
    sleep 3
    kill $P1
    echo "end"
    
```

```

    i=1
    i=2
    i=3
    end
    i=4
    i=5
    i=6
    i=7
    i=8
    i=9
    i=10
    
```

なぜこうなるのでしょうか。  
また、最初の実行と同じように、直ちにtest.shを終了するにはどうすればいいでしょうか。
CC BY-SA 4.0
2020-10-27T01:37:52.103
71528
2020-10-27T05:47:47.627
2020-10-27T04:55:35.770
3060
28998
question
linux bash
bash: &&で実行されるコマンドリストのkill
`$!`は **最後に実行された** バックグラウンド (非同期) コマンドの プロセス ID に展開されます。  
最後に実行されたのは`./test.sh && echo "yes"`であって`./test.sh`ではないので`$P1`に入るプロセスIDも別の値です。  
なので、`P1=$(pgrep test.sh)`と変更すれば期待通りに動作すると思います。
CC BY-SA 4.0
2020-10-27T04:54:47.330
71531
2020-10-27T04:54:47.330
25936
71528
answer
> また、最初の実行と同じように、直ちにtest.shを終了するにはどうすればいいでしょうか。

伽語蓮弥の回答にあるとおり、P1には`./test.sh && echo "yes"`のPIDが格納されます。  
`./test.sh`はP1の子のプロセスなので、

```

    kill $P1
    
```

の代わりに

```

    pkill -P ${P1}　＃親プロセスを指定してkill
    
```

とすることにより`./test.sh`が終了します。
CC BY-SA 4.0
2020-10-27T05:47:47.627
71532
2020-10-27T05:47:47.627
35558
71528
answer