简体   繁体   English

Mac Shell脚本获取主目录

[英]Mac Shell script get home directory

I need to get the home directory in my shell script so my coworkers can run it. 我需要在我的shell脚本中获取主目录,以便我的同事可以运行它。 What my shell does is really simple, it only copy some directories to another. 我的shell做的很简单,它只将一些目录复制到另一个目录。 I've used: 我用过:

$HOME, $ HOME,
$(whoami) $(WHOAMI)
even this: 即使这样:
ABSPATH=$(cd "$(dirname "$0")"; pwd), ABSPATH = $(cd“$(dirname”$ 0“)”; pwd),

but when I use the variable like this: 但是当我使用这样的变量时:

DIR= $ABSPATH/folder/afolder/bfolder/ DIR = $ ABSPATH / folder / afolder / bfolder /

and run it I receive this: 并运行它我得到这个:

/Users/theUser/Desktop/FusionTest.command: line 14: /Users/theUser/Desktop/folder/afolder/bfolder: is a directory /Users/theUser/Desktop/FusionTest.command:line 14:/ Users / theUser / Desktop / folder / afolder / bfolder:是一个目录
Copying to usage: cp [-R [-H | 复制到用法:cp [-R [-H | -L | -L | -P]] [-fi | -P]] [-fi | -n] [-apvX] source_file target_file cp [-R [-H | -n] [-apvX] source_file target_file cp [-R [-H | -L | -L | -P]] [-fi | -P]] [-fi | -n] [-apvX] source_file ... target_directory logout -n] [-apvX] source_file ... target_directory logout
[Process completed] [流程完成]

I'm using the command cp -r to copy all files and directories. 我正在使用命令cp -r来复制所有文件和目录。

Whay I am missing? 我错过了什么? or how can I do this?? 或者我该怎么做?

As the error message implies -r is the incorrect flag for recursive copying. 由于错误消息暗示-r是递归复制的错误标志。 The flag you want is -R (flags are case-sensitive). 您想要的标志是-R (标志区分大小写)。 As for the home directory, $HOME should always work. 至于主目录, $HOME应该始终有效。

Talk about several things here: 在这里谈几件事:

  1. How Macs handle HOME directories and a way to retrieve the actual HOME directory if it has been unset. Mac如何处理HOME目录以及如果未设置则检索实际HOME目录的方法。
  2. How to use command line parameters correctly because the GNU cp command on Linux allows you to do it the wrong way, and that has caused a lot of problems. 如何正确使用命令行参数,因为Linux上的GNU cp命令允许您以错误的方式执行,这导致了很多问题。
  3. How to use set -xv for debugging in your script. 如何在脚本中使用set -xv进行调试。 This will help you debug about 90% of the shell script errors you get. 这将帮助您调试大约90%的shell脚本错误。
  4. What I think is actually wrong in your script. 我认为你的脚本实际上是错误的。 Unfortunately, this is a wild guess due to a lack of information, but it's a pretty good guess. 不幸的是,由于缺乏信息,这是一个疯狂的猜测,但这是一个很好的猜测。

How Macs Handle Home Directories Mac如何处理主页目录

Mac OS X is a true Unix version. Mac OS X是一个真正的Unix版本。 In fact, it's even more Unix than Linux. 事实上,它甚至比Linux还要多。 Because of this, it should be fairly compatible with almost all systems. 因此,它应该与几乎所有系统完全兼容。

The Mac home directory are stored under the /Users directory. Mac主目录存储在/Users目录下。 In the default BASH shell that Mac uses (and even in the old Turbo Csh), you can use ~ as an alias to the $HOME . 在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.

If someone changed the HOME environment variable, you can use ~userName to get the correct value of the HOME directory: 如果有人更改了HOME环境变量,您可以使用~userName来获取HOME目录的正确值:

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

Command Line Parameters 命令行参数

The error probably doesn't have anything to do with the Macness of your computer. 该错误可能与您的计算机的Macness没有任何关系。 It's probably a standard problem you'd find on almost any computer. 这可能是几乎所有计算机上都会出现的标准问题。 The Mac's cp command takes either the -r or -R command. Mac的cp命令使用-r-R命令。 Unlike GNU's cp which is found on Linux systems, the Mac handles the command line parameters correctly . 与Linux系统上的GNU cp不同,Mac 正确处理命令行参数。

For example, on Linux, this is acceptable: 例如,在Linux上,这是可以接受的:

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

On Unix systems, that would probably fail. 在Unix系统上,这可能会失败。 You need the -r parameter after the command: 命令后需要-r参数:

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

If you're doing the cp command as in the first example, it won't work on Unix and won't work on a Mac. 如果您正在执行第一个示例中的cp命令,它将无法在Unix上运行,也无法在Mac上运行。

Debugging Shell Scripts 调试Shell脚本

Now, that we got some preliminaries out of the way, let's look how to debug your problem... 现在,我们已经完成了一些预备工作,让我们来看看如何调试你的问题......

Put set -xv before line #14 (maybe a few lines before just to be sure). 在第14行之前放置set -xv之前可能需要几行)。 This turns on script debugging. 这将打开脚本调试。 The -x parameter will echo the command line with interpolations before executing the line. -x参数将在执行行之前使用插值回显命令行。 This way, you can see what the actual command is being executed. 这样,您可以看到正在执行的实际命令。

The -v parameter will echo the line as is without interpolation. -v参数将按原样回显该行而不进行插值。 That way, you can see what the command looked like and maybe detect an error in the setting of an environment variable. 这样,您可以看到命令的外观,并可能在环境变量的设置中检测到错误。

Here's a simple script: 这是一个简单的脚本:

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

Executing the script, we get: 执行脚本,我们得到:

 $ test.sh
 Hello David!
 $

Now, I'll do this: 现在,我会这样做:

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

Now, I'll get this: 现在,我会得到这个:

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

Another neat trick is to set PS4 to " ${LINENO}: ". 另一个巧妙的技巧是将PS4设置为“ ${LINENO}: ”。 That will prepend each line with the line number rather than just a + as above: 这将在每行前面加上行号而不是上面的+

The Possible Solution 可能的解决方案

I have a feeling that the problem is that you have a directory name with spaces in it. 我有一种感觉,问题是你有一个带空格的目录名。 Quote directory and file names to prevent these spaces from causing you problems: 引用目录和文件名以防止这些空格导致您出现问题:

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.

Conclusions 结论

Don't worry about your Mac being different . 不要担心你的Mac会有所不同 It's just another Unix system. 它只是另一个Unix系统。 Make sure that you're using the command line parameters correctly cp -R $dir1 $dir2 and not cp $dir $dir2 -R . 确保正确使用命令行参数cp -R $dir1 $dir2而不是cp $dir $dir2 -R Use set -xv to help you locate the errors, and get into the habit of quoting your environment variables since a space or tab in the environment variable's value could cause the program to fail. 使用set -xv可以帮助您找到错误,并养成引用环境变量的习惯,因为环境变量值中的空格或制表符可能导致程序失败。


Note on Mac OS X - Lion 关于Mac OS X的注意事项 - Lion

According to the manpage, -r is no longer documented as an option. 根据联机帮助页, -r不再作为选项记录。 However it does work. 但它确实有效。 According to the man page: 根据手册页:

Historic versions of the cp utility had a -r option. cp实用程序的历史版本具有-r选项。 This implementation supports that option; 此实现支持该选项; however, its use is strongly discouraged, as it does not correctly copy special files, symbolic links, or fife's. 然而,强烈建议不要使用它,因为它没有正确复制特殊文件,符号链接或横笛。

However, cp -R should work on both Linux and is documented in Mac OS X as the recursive copy flag. 但是, cp -R应该可以在Linux上运行,并且在Mac OS X中记录为递归复制标志。

I don't like ~ in scripts and $HOME fails sometimes depending on the shell you're using - maybe not on OSX, but I don't care.. 我不喜欢〜脚本和$ HOME失败有时取决于你正在使用的shell - 也许不在OSX上,但我不在乎..

Somewhere somehow the system has a record of where a user's home directory is and $HOME is set from that. 某处某个地方,系统记录了用户主目录的位置,并设置了$ HOME。

Specifically, I am usually trying to find the home dir of another user (and again not a fan of ~ abbreviations in scripts - call it preference) For OSX, I use this -- 具体来说,我通常试图找到另一个用户的主目录(并且再次不是脚本中的〜缩写的粉丝 - 称之为偏好)对于OSX,我使用这个 -

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

Everywhere else, I usually grep /etc/passwd, but thinking on it, finger would probably be more universal. 在其他地方,我通常grep / etc / passwd,但想一想,手指可能会更普遍。

This is my quick and dirty answer. 这是我快速而又肮脏的答案。 There will be a better solution if you know OSX internal better - but care factor? 如果你知道OSX内部更好 - 但是关心因素会有更好的解决方案吗? This works for me 这适合我

$HOME should be set, but it is not guaranteed. 应设置$ HOME,但不保证。 It is possible for a user to override this variable. 用户可以覆盖此变量。 Another option is to use getent . 另一种选择是使用getent

IFS=: read -r _ _ _ _ _ homedir _ < <(getent passwd myuser)
echo "$homedir"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM