数値nを引数として使用し、作業ディレクトリでlsを実行して、リストされたn番目のディレクトリにディレクトリを変更するコマンドを提供するbashスクリプトを作成しようとしています。これが私が持っているものです:
#! /bin/bash -
arg=$(ls --group-directories-first | awk -v first=$1 'NR == first' | tr -d '[[:space:]]')
cd $arg
これはうまくいきません。実行すると何も起こりません。
最初の行は、私が望む方法でディレクトリ名をキャプチャするようです。スクリプトを次に変更すると
#! /bin/bash -
arg=$(ls --group-directories-first | awk -v first=$1 'NR == first' | tr -d '[[:space:]]')
echo $arg
最初のディレクトリがbinのディレクトリで実行され、パラメータ1を指定すると、スクリプトは "bin"を出力します。
[user@manjaro ~]$ ls
bin/
Desktop/
Documents/
Downloads/
[user@manjaro ~]$ cdn 1
bin
それでは、元のバージョンを使用するときに「bin」なしでCDを作成してbinに変更するのはなぜですか?どうやって変えますか?
最後のポイント。スクリプトの外部で同様の操作を実行しようとすると正常に動作します。
[user@manjaro ~]$ foo=bin
[user@manjaro ~]$ cd $foo
[user@manjaro bin]$ pwd
/home/user/bin
またなぜ?
答え1
作業ディレクトリは実行中のプロセスの属性であり、スクリプトはシェルとは異なるプロセスで実行されます。したがって、スクリプト内のディレクトリを変更してもインタラクティブシェルには影響しません。これは良いことです。それ以外の場合、このようなものはfind
任意のディレクトリにシェルを残す可能性があります。職場で邪魔する場合。
実際に動作するか、作業ディレクトリであるかを確認するために、pwd
スクリプトを後ろに置くことができます。cd
スクリプト多様性。その後、スクリプトが終了します。
これをシェル関数に変更します。
cdn() {
arg=$(ls --group-directories-first |
awk -v first="$1" 'NR == first' | tr -d '[[:space:]]')
cd -- "$arg"
}
(あなたがそこになぜなのかわかりませんtr
。)
またはBashで配列を使用してください。
cdn() {
dirs=( ./*/ )
if [[ ${#dirs[@]} == 0 ]]; then
echo "No directories!" >&2
return 1
fi
# minus one to go from one-based to zero-based indexing
cd -- "${dirs[$1 - 1]}"
}
ファイル名に改行やスペースがある場合、後者はより安全です。 (指定されたインデックスに一致するディレクトリが存在するかどうかを確認しません。存在しない場合は、単に実行してcd ''
現在のディレクトリに「変更」します。)