8

同僚が実行できるように、シェル スクリプトでホーム ディレクトリを取得する必要があります。私のシェルが行うことは非常に単純です。いくつかのディレクトリを別のディレクトリにコピーするだけです。私が使用した:

$HOME,
$(whoami)
これでも:
ABSPATH=$(cd "$(dirname "$0")"; pwd),

しかし、次のように変数を使用すると:

DIR= $ABSPATH/フォルダー/a フォルダー/b フォルダー/

実行すると、次のようになります。

/Users/theUser/Desktop/FusionTest.command: 14 行目: /Users/theUser/Desktop/folder/afolder/bfolder: はディレクトリです
コピー先の使用法: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] ソース_ファイル ターゲット_ファイル cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory logout
[処理完了]

コマンド cp -r を使用して、すべてのファイルとディレクトリをコピーしています。

なぜ私は行方不明ですか?またはどうすればこれを行うことができますか??

4

4 に答える 4

8

エラー メッセージが示すよう-rに、再帰コピーのフラグが正しくありません。必要なフラグは-R(フラグは大文字と小文字が区別されます) です。ホームディレクトリに関しては、$HOME常に機能するはずです。

于 2012-06-22T18:10:40.017 に答える
5

ここでいくつかのことについて話します。

  1. Mac がHOMEディレクトリを処理する方法と、実際のディレクトリが設定されていない場合に取得する方法HOME
  2. cpLinux の GNU コマンドでは間違った方法でコマンド ライン パラメーターを使用できるため、コマンド ライン パラメーターを正しく使用する方法。多くの問題が発生しています。
  3. set -xvスクリプトでのデバッグに使用する方法。これにより、発生するシェル スクリプト エラーの約 90% をデバッグできます。
  4. 私が思うことは、あなたのスクリプトで実際に間違っています。残念ながら、これは情報が不足しているため大雑把な推測ですが、かなり良い推測です。

Mac がホーム ディレクトリを処理する方法

Mac OS X は真の Unix バージョンです。実際、これは Linux よりもさらに Unix に近いものです。このため、ほぼすべてのシステムと互換性があります。

Mac のホーム ディレクトリは、この/Usersディレクトリの下に格納されます。Mac が使用するデフォルトの BASH シェル (および古い Turbo Csh でさえ) では~$HOME.

 $ echo "$HOME"   # Use quotes around directory and file names to avoid 
 $                # problems with white spaces.
 $ echo ~         # Echos the `$HOME` directory.

誰かがHOME環境変数を変更した場合は、ディレクトリの正しい~userNameを取得するために使用できます。HOME

$ echo $HOME
/Users/david
HOME=/tmp
$ echo $HOME
/tmp
$ echo ~
/tmp
$ echo ~david
 /Users/david
$ HOME=~david   #Fixed!

コマンド ライン パラメータ

このエラーは、お使いのコンピューターのMac 性とはおそらく関係ありません。おそらく、ほとんどすべてのコンピューターで見られる標準的な問題です。Mac のcpコマンドは、-rまたは-Rコマンドのいずれかを取ります。cpLinux システムに見られるGNU とは異なり、Mac はコマンド ライン パラメータを正しく処理します。

たとえば、Linux では、これは許容されます。

$ cp "$dir" "$dir2" -r

Unix システムでは、おそらく失敗します。-rコマンドの後にパラメーターが必要です。

$ cp -r "$dir" "$dir2"

最初の例のようにコマンドを実行するcpと、Unix でも Mac でも機能しません。

シェル スクリプトのデバッグ

さて、いくつかの準備が整ったので、問題をデバッグする方法を見てみましょう...

14 行目の前に置きset -xvます (念のため、数行前にすることもできます)。これにより、スクリプトのデバッグがオンになります。この-xパラメーターは、コマンドラインを実行する前に補間を使用してコマンドラインをエコーし​​ます。このようにして、実際に実行されているコマンドを確認できます。

パラメータは、補間なしでラインをそのまま-vエコーします。そうすれば、コマンドがどのように表示されるかを確認でき、環境変数の設定のエラーを検出できる可能性があります。

簡単なスクリプトを次に示します。

 name="David"
 echo "Hello $name!"

スクリプトを実行すると、次のようになります。

 $ test.sh
 Hello David!
 $

今、私はこれを行います:

 set -xv
 name="David"
 echo "Hello $name!"
 set +xv     #Turns off the -xv flags

今、私はこれを取得します:

 $ ./test.sh
 name="David"
 + name=David
 echo "Hello $name!"
 + echo 'Hello David!'
 Hello David!

もう 1 つの巧妙なトリックは、PS4" ${LINENO}:" に設定することです。+これにより、上記の a だけでなく、各行の先頭に行番号が追加されます。

可能な解決策

問題は、ディレクトリ名にスペースが含まれていることだと思います。これらのスペースが問題を引き起こさないように、ディレクトリとファイル名を引用してください。

my_pictures=$HOME/"My Pictures"
cp -R $my_pictures $target     #Won't work due to the space between "My" & "Pictures"
cp -R "$my_pictures" "$target" #The quotes solve the problem.

結論

お使いの Mac が異なっていることを心配する必要はありません。それは単なる別の Unix システムです。cp -R $dir1 $dir2コマンド ライン パラメータを正しく使用していることを確認してくださいcp $dir $dir2 -R。エラーを見つけやすくするために使用set -xvし、環境変数の値にスペースやタブがあるとプログラムが失敗する可能性があるため、環境変数を引用する習慣を身につけてください。


Mac OS X に関する注意 - ライオン

マンページによると-r、オプションとして文書化されなくなりました。ただし、機能します。マニュアルページによると:

cp ユーティリティの歴史的なバージョンには -r オプションがありました。この実装はそのオプションをサポートしています。ただし、特別なファイル、シンボリック リンク、ファイルを正しくコピーしないため、使用しないことを強くお勧めします。

ただし、cp -RLinux の両方で動作するはずであり、Mac OS X では再帰的コピー フラグとして文書化されています。

于 2012-06-22T20:34:22.827 に答える
1

$HOME を設定する必要がありますが、保証されていません。ユーザーはこの変数をオーバーライドできます。別のオプションは、を使用することgetentです。

IFS=: read -r _ _ _ _ _ homedir _ < <(getent passwd myuser)
echo "$homedir"
于 2012-06-22T18:20:38.737 に答える
1

私はスクリプトで ~ が好きではなく、使用しているシェルによっては $HOME が失敗することがあります - OSX ではそうではないかもしれませんが、私は気にしません..

どういうわけか、システムにはユーザーのホームディレクトリがどこにあるかの記録があり、そこから $HOME が設定されます。

具体的には、私は通常、別のユーザーのホームディレクトリを見つけようとしています(スクリプトの〜の略語のファンではありません-好みと呼びます)OSXの場合、これを使用します-

 finger $username | awk '/^Directory/ {print $2}'

他の場所では、通常 /etc/passwd を grep しますが、考えてみると、finger の方がおそらくより普遍的なものになるでしょう。

これは私の迅速で汚い答えです。OSXの内部をよく知っていれば、より良い解決策がありますが、注意が必要ですか? これは私のために働く

于 2016-04-23T04:38:33.693 に答える