web-dev-qa-db-ja.com

pwdは何を出力しますか?

シェルスクリプトのコマンドpwdは、シェルスクリプトがあるディレクトリを出力しますか?

6
mkdrive2

ここには、3つの独立した「ディレクトリ」があります。

  1. 現在のシェルの現在の作業ディレクトリ
  2. シェルスクリプトの現在の作業ディレクトリ、および
  3. シェルスクリプトを含むディレクトリ。

それらが独立していることを示すために、/ tmp/pwd.shに保存された以下を含むシェルスクリプトを記述できます。

#!/bin/sh
pwd
cd /var 
pwd

次に、pwd(上記の#1)を/に変更します。

cd /

そしてスクリプトを実行します:

/tmp/pwd.sh

これは、既存のpwdをデモンストレーションすることから始まり(#1)、それを/ varに変更して再度表示します(#2)。これらのpwdはいずれも、/ tmp/pwd.shを含むディレクトリ「/ tmp」ではありません(#3)。

19
Jeff Schaller

現在の(または現在の)作業ディレクトリ

シェルスクリプトのコマンドpwdは、シェルスクリプトがあるディレクトリを返しますか?

番号。

最初に、定義上、シェルスクリプトまたはシェルコマンドは、0〜255の数値の終了ステータス以外のものを返しません。これは公理的ですが、一般に、これらの種類の質問をしたときに意味するものではありません。

次に、pwdBourne Shell builtin であり、標準のシステムバイナリでもあります。いずれかprints論理または物理現在の作業ディレクトリ

  1. スクリプトまたはバイナリを呼び出すときのディレクトリ構造内の場所。
  2. cdを使用して作業ディレクトリを変更した後の現在の場所、またはpushdやpopdなどの現在の作業ディレクトリを変更する他のユーティリティとビルトイン。

現在のスクリプトのディレクトリが必要な場合は、以下の最後のセクションで説明するように、dirnameユーティリティを使用します。

pwdのクイックテスト

pwdが実際に何を出力するかを確認する簡単なテストとして、次のコマンドを実行できます。

# Create a Shell script containing pwd.
cat <<-EOF > /tmp/test_pwd.sh
#!/bin/sh

pwd
EOF

# Make the script executable.
chmod 755 /tmp/test_pwd.sh

# Go somewhere on the filesystem, and call the test script.
cd /etc
/tmp/test_pwd.sh

現在の作業ディレクトリは現在/etcであるため、/tmpではなく/etcが出力されます。これは予想される動作です。

スクリプトを含むディレクトリを取得する

現在のスクリプトのディレクトリを見つけたいので、おそらくこの質問をしているでしょう。一般的なケースでは、以下は迅速で汚いソリューションです。

#!/usr/bin/env bash
echo $(dirname "$0")

$0には通常、実行中のスクリプトを呼び出すために使用されるパス名が含まれており、シェル拡張はdirnameユーティリティを使用してファイル名部分を除くパスを返すため、これは機能します。 Bashパラメータ展開"${0%/*}"を使用すると、同様のことを行うことができますが、移植性は低くなります。

もちろん、これは非常に単純化しすぎです。 Bashマニュアル (特に、位置パラメータ、特殊パラメータ、およびBASH_SOURCEに関するセクション)と、readlinkおよびrealpathは、Edgeのケースが何であるかを完全に理解するためのものです。

ただし、日常のスクリプトでは、$0のディレクトリコンポーネントで、知りたいことを十分に伝えることができます。 $0が実際に必要な情報を保持しておらず、次のようなより複雑な構成が必要な場合に、複雑なことを行っている場合:

echo $(dirname "$(realpath "$0")")

そして、あなたはおそらくあなたの人生を必要以上に難しくしているのでしょう。

7
CodeGnome

pwdは、現在の作業ディレクトリを開けない場合を除き、0を返します。

mkdir /tmp/d; cd "$_"
pwd && pwd -P; echo "$?"
rmdir ../d
pwd && pwd -P; echo "$?"

/tmp/d
/tmp/d
0
/tmp/d
pwd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
1
5
user156177

cwdと呼ばれるこの概念があり、実行中のすべてのプロセスが追跡します。

言い換えれば、カーネルは各プロセスのcwdの考えを保持しています。

その =で読み取ることができます (/ procを備えたシステムの場合):

readlink /proc/$PID_of_PROCESS/cwd

実行中のシェル(そのPIDは$$である必要があります)の場合:

$ readlink /proc/$$/cwd

シェルは、変数$ PWDとコマンドpwdで同じ情報を追跡します(たまに同期が取れなくなることがあります)。

$ cd /tmp; echo "Present working directory: $PWD"
Present working directory: /tmp
$ cd /tmp; echo "Current working directory: $(pwd)"
Current working directory: /tmp

したがって、pwdコマンドは各プロセスのcwdを表示します。

The place each process stands inside the directory tree.

シェル、スクリプト、またはプロセスがcdを実行するたびに、これらのすべての変数が更新されます(一部の例外的なケースを除く)。

シェルは、たとえばcd /tmpを実行することにより、pwdを変更できます。

スクリプトは、実行中のシェルにpwdcd /tmpに変更するように指示することもできます。

または、他のcプロセスがカーネルを呼び出して、cd /tmpに相当するものを実行する場合もあります。

すべての場合において、カーネルcwdおよび(プロセスがシェルの場合)シェルのpwdが更新されます。

3
user79743

スクリプトが存在する場所ではなく、呼び出された場所から実行されます。

ここにtry.shがあります:

echo "The current working directory: $PWD"

この出力により、より明確になります。

[akarpe@ADM-PROD-OMNI ~]$ sh try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh try/try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh ./try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh ./try/try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ cd try
[akarpe@ADM-PROD-OMNI try]$ sh ./try.sh
The current working directory: /mnt/home/akarpe/try
[akarpe@ADM-PROD-OMNI try]$ sh ../try.sh
The current working directory: /mnt/home/akarpe/try
1
Ashish Karpe