Mac Shell脚本获取主目录

Raf*_*eno 6 macos bash cp home-directory

我需要在我的shell脚本中获取主目录,以便我的同事可以运行它.我的shell做的很简单,它只将一些目录复制到另一个目录.我用过:

$ HOME,
$(whoami)
甚至这个:
ABSPATH = $(cd"$(dirname"$ 0")"; pwd),

但是当我使用这样的变量时:

DIR = $ ABSPATH/folder/afolder/bfolder /

并运行它我得到这个:

/Users/theUser/Desktop/FusionTest.command:line 14:/ Users/theUser/Desktop/folder/afolder/bfolder:是一个目录
复制到用法:cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory logout
[已完成处理]

我正在使用命令cp -r来复制所有文件和目录.

我错过了什么?或者我该怎么做?

You*_*You 7

因为错误消息暗示-r是递归复制的错误标志.你想要的标志是-R(标志区分大小写).至于主目录,$HOME应该始终有效.

  • @jordanm:它定义了`-r`,但不要求它做任何有用的事情("如果指定了-r选项,则行为是实现定义的.").我会避免它...... (2认同)

Dav*_* W. 5

这里说几件事:

  1. Mac 如何处理HOME目录以及在HOME未设置的情况下检索实际目录的方法。
  2. 如何正确使用命令行参数,因为cpLinux 上的 GNU命令允许您以错误的方式使用命令行参数,这导致了很多问题。
  3. 如何set -xv在脚本中进行调试。这将帮助您调试大约 90% 的 shell 脚本错误。
  4. 我认为您的脚本中实际上是错误的。不幸的是,由于缺乏信息,这是一个疯狂的猜测,但这是一个很好的猜测。

Mac 如何处理主目录

Mac OS X 是真正的 Unix 版本。事实上,它甚至比 Linux 更像 Unix。因此,它应该与几乎所有系统都相当兼容。

Mac 主目录存储在该/Users目录下。在 Mac 使用的默认 BASH shell(甚至在旧的 Turbo Csh 中)中,您可以将其~用作$HOME.

 $ echo "$HOME"   # Use quotes around directory and file names to avoid 
 $                # problems with white spaces.
 $ echo ~         # Echos the `$HOME` directory.
Run Code Online (Sandbox Code Playgroud)

如果有人更改了HOME环境变量,则可以使用~userName来获取目录的正确HOME

$ echo $HOME
/Users/david
HOME=/tmp
$ echo $HOME
/tmp
$ echo ~
/tmp
$ echo ~david
 /Users/david
$ HOME=~david   #Fixed!
Run Code Online (Sandbox Code Playgroud)

命令行参数

该错误可能与您计算机的Macness 无关。这可能是您在几乎所有计算机上都会发现的标准问题。Mac 的cp命令采用-ror-R命令。与cpLinux 系统上的GNU 不同,Mac正确处理命令行参数。

例如,在 Linux 上,这是可以接受的:

$ cp "$dir" "$dir2" -r
Run Code Online (Sandbox Code Playgroud)

在 Unix 系统上,这可能会失败。-r命令后需要参数:

$ cp -r "$dir" "$dir2"
Run Code Online (Sandbox Code Playgroud)

如果您cp像第一个示例那样执行命令,它将无法在 Unix 上运行,也无法在 Mac 上运行。

调试 Shell 脚本

现在,我们已经完成了一些预备工作,让我们看看如何调试您的问题......

放在set -xv第 14 行之前(为了确定,可能在前面几行)。这将打开脚本调试。该-x参数将在执行该行之前用插值回显命令行。这样,您就可以看到正在执行的实际命令。

-v参数将在没有插值的情况下按原样回显该行。这样,您可以看到命令的样子,并可能检测到环境变量设置中的错误。

这是一个简单的脚本:

 name="David"
 echo "Hello $name!"
Run Code Online (Sandbox Code Playgroud)

执行脚本,我们得到:

 $ test.sh
 Hello David!
 $
Run Code Online (Sandbox Code Playgroud)

现在,我会这样做:

 set -xv
 name="David"
 echo "Hello $name!"
 set +xv     #Turns off the -xv flags
Run Code Online (Sandbox Code Playgroud)

现在,我会得到这个:

 $ ./test.sh
 name="David"
 + name=David
 echo "Hello $name!"
 + echo 'Hello David!'
 Hello David!
Run Code Online (Sandbox Code Playgroud)

另一个巧妙的技巧是设置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.
Run Code Online (Sandbox Code Playgroud)

结论

不用担心您的 Mac与众不同。它只是另一个 Unix 系统。确保您正确使用命令行参数cp -R $dir1 $dir2而不是cp $dir $dir2 -R. 使用set -xv以帮助您找到的错误,并进入,因为在环境变量的值空格或制表符引用您的环境变量的习惯可能会导致程序失败。


Mac OS X 上的注意事项 - Lion

根据联机帮助页,-r不再记录为选项。但是它确实有效。根据手册页:

cp 实用程序的历史版本有一个 -r 选项。此实现支持该选项;但是,强烈建议不要使用它,因为它不能正确复制特殊文件、符号链接或 fife 文件。

但是,cp -R应该适用于 Linux,并且在 Mac OS X 中记录为递归复制标志。