找不到realpath命令


24

我有debian挤amd64。我当前的shell是bash。如果我在终端中写了以下内容,则可以使用:

$ uname -a
Linux core 2.6.32-5-amd64 #1 SMP Fri May 10 08:43:19 UTC 2013 x86_64 GNU/Linux
$ echo $SHELL
/bin/bash                                                                                                                                                                                     
$ echo $(realpath test.sh)                                                                                                                                                     
/home/ffortier/test.sh

我的test.sh文件看起来像这样:

#!/bin/bash
echo $(realpath "$1")

如果我尝试执行以下操作,则会出现错误

$ ./test.sh test.sh 
./test.sh: line 2: realpath: command not found

如何在bash文件中使用realpath命令?

附加信息

$ type -a realpath
realpath is a function                                                                                                                                                                        
realpath ()                                                                                                                                                                                   
{                                                                                                                                                                                             
    f=$@;                                                                                                                                                                                     
    if [ -d "$f" ]; then                                                                                                                                                                      
        base="";                                                                                                                                                                              
        dir="$f";                                                                                                                                                                             
    else                                                                                                                                                                                      
        base="/$(basename "$f")";                                                                                                                                                             
        dir=$(dirname "$f");                                                                                                                                                                  
    fi;                                                                                                                                                                                       
    dir=$(cd "$dir" && /bin/pwd);                                                                                                                                                             
    echo "$dir$base"                                                                                                                                                                          
}           

Answers:


9

realpath是实际命令还是脚本?我将检查它的来源。

$ type -a realpath

我对该工具不熟悉,因此它可能不属于您的正常发行版,它可能安装在非标准位置,该位置不在Bash上,$PATH但在您的登录环境内$PATH

无论如何,以上type命令将向您显示该命令的来源,此时您可以更改在脚本中调用它的方法,如下所示:

echo $(/path/to/realpath test.sh)

或修改您的脚本$PATH,使其也包含此非标准位置。

外壳中的功能

调用Shell脚本时,大部分环境不会被调用。如果考虑到这一点,这很有意义,因为您通常不希望脚本具有用户环境可能拥有的所有其他负担。

您可以确定哪个源文件提供了此功能并提供了该源,或者只是指示Bash合并您的登录环境。

#!/bin/bash -l
echo $(realpath "$1")

这是一个功能,请参见编辑
弗朗西斯(Francis)

@Francis-是的,调用脚本时不包含这些功能。如果您希望它们出现,则需要采购它们。找出提供功能的文件并提供其来源。如果您只是想要整个环境。然后将您的通话修改为bash #!/bin/bash -l
slm

我如何找到此功能的来源?
弗朗西斯

1
@mikeserv-谢谢,当我撰写本文时,我仍在使用Fedora 14(不包含)realpath。我的Fedora 19系统现在包含此工具。还要注意,OP使用的是Debian w / 2.6内核,因此realpath考虑到它的年龄,他的系统也将丢失。
slm

1
@mikeserv-是的,我很惊讶,这是一个古老的问题,但是有关的信息对command我仍然有用。这是一种可移植的方式,可以完成我在POSIX Shell上展示的内容。
slm

27

至少有两个程序称为realpath

  • GNU coreutils不包含时的旧程序readlink -f。现在不推荐使用readlink -f,因此许多发行版本已停止使用它。
  • realpath程序在GNU coreutils 8.15中引入。这太老了,无法挤入Debian,甚至喘不过气来。在撰写本文时,Debian stable也没有发货。这个程序非常接近readlink -f

出于某种原因,您拥有一个shell函数,该函数部分模拟的行为realpath。此仿真是局部的:如果在符号链接上调用它,则它不会跟随符号链接。

由于这是一个外壳函数,大概是通过或通过加载的.bashrc,因此仅适用于在交互式外壳中运行的代码。如果您希望它可用于其他程序(假设您正在运行Linux),请创建一个模拟realpath以下脚本:

#!/bin/sh
readlink -f -- "$@"

(这不会模拟realpath很少使用的命令行选项。)


2
我在coreutils git repo中找不到任何证据表明该realpath程序被coreutils弃用,或者默认情况下未构建。所以Debian必须删除它。
卡兹(Kaz)2014年

@Kaz哦,很复杂,coreutils最近(8.15)引入了一个realpath二进制文件,该二进制文件与接近但并不完全相同readlink -f。Debian马stable搭载8.13。Debian stable 选择保留旧版程序
吉尔(Gilles)'所以

这并不是最近-这是2012年一月savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv

1
@mikeserv对于该问题的分发(Debian压榨),还太新。对于目前的Debian稳定版来说,甚至太新了。
吉尔(Gilles)'所以

有点吓人。他们几岁了openssl
mikeserv

8

它仅在shell中有效,因为脚本文件的作用域不同,并且无法访问rc文件中定义的本地函数和别名。而且realpath命令实际上在您的系统中不存在。

因此,可以realpath从软件包中进行安装,定义自己的功能(作为脚本的一部分,请查看一些示例),或者在定义了脚本的脚本中提供rc文件(例如. ~/.bashrc)。


realpath如果不存在,请按照以下步骤进行安装:

  • Ubuntu: sudo apt-get install coreutils
  • OS X: brew install coreutils

Ubuntu和Debian

在Debian或Ubuntu上realpath,默认情况下应该安装。我已经检查了最近的Debian 8(Jessie),它似乎已coreutils默认安装。

使用新的VM映像进行了测试:

$ vagrant init debian/jessie64 && vagrant up --provider virtualbox && vagrant ssh
$ vagrant init ubuntu/vivid64 && vagrant up --provider virtualbox && vagrant ssh

然后在VM中:

$ type -a realpath
realpath is /usr/bin/realpath

除了realpath,您还可以使用包提供的readlink -f file(或greadlinkcoreutils


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.