【问题标题】:In an OS X shell script, how can I get a file path from its inode?在 OS X shell 脚本中,如何从其 inode 获取文件路径?
【发布时间】:2014-11-20 20:25:19
【问题描述】:

我有一个文件列表为:<volume name>:<directory inode>:<file name>。例如,:Foo:33103829:IMG_2837.JPG。如何获取文件路径?

我在这里找到了an answer,这看起来正是我想要的,但我无法让它工作。 The answer 说在 OS X 上有一个“魔法”目录/.vol 可以在 inode 上运行。 ls 告诉我/.vol 存在,但不包含任何内容,即使被 inode 访问:

# verify that /.vol exists:
~$ ls -ld /.vol
drwxr-xr-x@ 2 root  wheel  68 May 18  2009 /.vol/

# get inode of volume Foo
~$ ls -id /Volumes/Foo
32659974 /Volumes/Foo@

# access volume Foo by idnode
~$ ls /.vol/32659974
ls: /.vol/32659974: No such file or directory

# access volume Foo by idnode
~$ cd /.vol/32659974
cd: /.vol/32659974: No such file or directory

# access volume by inode using GetFileInfo
~$ GetFileInfo /.vol/32659974
GetFileInfo: could not refer to file (-43)

【问题讨论】:

  • 您在该问题中看到GetFileInfo 答案了吗?即使 accepted 答案对您不起作用(不足为奇,因为它特定于目录 - 并且不会隐藏该限制)并不意味着其他人不值得研究。
  • 顺便说一句,虽然对于目录来说,假设每个 inode 只存在一个路径是安全的,但对于文件来说,这根本不是一个安全的假设。
  • 嗨@CharlesDuffy,GetFileInfo 是等效的,因为它还依赖于/.vol 工作。我可以将其添加到我的问题中。
  • 在我的情况下,我正在尝试有条不紊地进行,所以第 1 步是验证我可以通过它的 inode 访问一个卷(根据另一个答案中的示例),我不能。如果可以,我会尝试访问该目录,如果可以,我会按文件名访问该文件,我有。

标签: macos shell inode


【解决方案1】:

原来的问题是我从ls -i 获取卷的inode 号,它无法通过/.vol 访问,它需要设备ID。当我改为使用stat(正如我在an answer here 中看到的)获取卷的设备ID 时,它可以工作。

# ls -id returns inode as '32659974'
~$ ls -id /Volumes/Foo
32659974 /Volumes/Foo@

# stat returns device ID as '234881026' and confirms inode is '32659974'
~$ stat /Volumes/Foo
234881026 32659974 lrwxr-xr-x 1 root admin 0 1 "Sep 16 14:31:52 2014" "Sep 16 14:31:52 2014" "Sep 16 14:31:52 2014" "Sep 16 14:31:52 2014" 4096 8 0 /Volumes/Foo

# access file using ./vol/<device ID>/<inode>
~$ cd /.vol/234881026/1017800
:../Prague 2011 March$

【讨论】:

  • stat输出的第一个数字不是inode,是设备ID。将使用stat -s 时的输出与stat(2) man pagestruct stat 的记录字段进行比较。您会注意到stat 也报告了inode 编号,但inode 编号仅在给定设备的上下文中才有意义,这就是/.vol 文件系统要求您先提供设备ID 再提供inode 的原因。
  • 我只是在阅读 lstat() 手册页并打算更新我的答案,但你打败了我,@KenThomases。线索应该是stat 返回的第二个数字与ls -id 返回的数字相同;这就是让我开始阅读 stat 的手册页的原因,导致 lstat 和关于设备 ID 与 inode 的灯泡。
【解决方案2】:

你可以使用这个脚本

#!/bin/sh
export PATH=/bin:/usr/bin
while IFS=: read -r vol inode name
do
    [[ -e "/Volumes/$vol" ]] || continue
    eval $(stat -s "/Volumes/$vol")
    fpath=$(GetFileInfo "/.vol/$st_dev/$inode" | perl -ne 'print "$2\n" if m/^(directory|file):\s*"(.*)"/;')
    printf "%s:%s:%s:%s" "$vol" $inode "$name" "$fpath"
    bname=$(basename "$fpath")
    [[ "$bname" == "$name" ]] && printf "\n" || printf " #DIFF NAMES\n"
done
  • 另存为v2p.sh
  • chmod 755 v2p.sh
  • 将其用作./v2p.sh &lt; your_input_file &gt;output_file

从输入喜欢

jhdd:60533283:aliases
jhdd:60526259:apache2
Tunnelblick Uninstaller:19:Online Documentation.webloc
jhdd:68032325:auto_smb
jhdd:60526617:bashrc

生产

jhdd:60533283:aliases:/private/etc/postfix/aliases
jhdd:60526259:apache2:/private/etc/apache2
Tunnelblick Uninstaller:19:Online Documentation.webloc:/Volumes/Tunnelblick Uninstaller/Online Documentation.webloc
jhdd:68032325:auto_smb:/private/etc/auto_smb
jhdd:60526617:bashrc:/private/etc/bashrc

例如将路径添加到末尾作为新的冒号分隔字段

【讨论】:

    猜你喜欢
    • 2011-08-16
    • 2011-07-15
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    相关资源
    最近更新 更多