dongyi7669 2016-08-15 22:19
浏览 39
已采纳

如何在纯Go语言的Linux上实现“ file -s <file>”?

Intent:
Does Go have the functionality (package or otherwise) to perform a special file stat on Linux akin to the command file -s <path>

Example:

[root@localhost ~]# file /proc/uptime
/proc/uptime: empty
[root@localhost ~]# file -s /proc/uptime
/proc/uptime: ASCII text

Use Case:
I have a fileglob of files in /proc/* that I need to very quickly detect if they are truly empty instead of appearing to be empty.

Using The os Package:

Code:

result,_ := os.Stat("/proc/uptime")
fmt.Println("Name:",result.Name()," Size:",result.Size()," Mode:",int(result.Mode()))
fmt.Printf("%q",result)

Result:

Name: uptime  Size: 0  Mode: 292
&{"uptime" '\x00' 'Ĥ' {%!q(int64=63606896088) %!q(int32=413685520) %!q(*time.Location=&{ [] [] 0 0 <nil>})} {'\x03' %!q(uint64=4026532071) '\x01' '脤' '\x00' '\x00' '\x00' '\x00' '\x00' 'Ѐ' '\x00' {%!q(int64=1471299288) %!q(int64=413685520)} {%!q(int64=1471299288) %!q(int64=413685520)} {%!q(int64=1471299288) %!q(int64=413685520)} ['\x00' '\x00' '\x00']}}

Obvious Workaround:
There is the obvious workaround of the following. But it's a little over the top to need to call in a bash shell in order to get file stats.

output,_ := exec.Command("bash","-c","file -s","/proc/uptime").Output()
//parse output etc...

EDIT/MY PRACTICAL USE CASE:
Quickly determining which files are zero size without needing to read each one of them first.

file -s /cgroup/memory/lsf/<cluster>/*/tasks | <clean up commands> | uniq -c
6 /cgroup/memory/lsf/<cluster>/<jobid>/tasks: ASCII text
805 /cgroup/memory/lsf/<cluster>/<jobid>/tasks: empty

So in this case, I know that only those 6 jobs are running and the rest (805) have terminated. Reading the file works like this:

# cat /cgroup/memory/lsf/<cluster>/<jobid>/tasks
#

or

# cat /cgroup/memory/lsf/<cluster>/<jobid>/tasks
12352
53455
...
  • 写回答

2条回答 默认 最新

  • dpge74512 2016-08-16 05:23
    关注

    I'm afraid you might be confusing matters here: file is special in precisely a way it "knows" a set of heuristics to carry out its tasks.

    To my knowledge, Go does not have anything like this in its standard library, and I've not came across a 3rd-party package implementing a file-like functionality (though I invite you to search by relevant keywords on http://godoc.org)

    On the other hand, Go provides full access to the syscall interface of the underlying OS so when it comes to querying the OS in a way file does it, there's nothing you could not do in plain Go.

    So I suggest you to just fetch the source code of file, learn what it does in its mode turned on by the "-s" command-line option and implement that in your Go code. We'll try to have you with specific problems doing that — should you have any.

    Update

    Looks like I've managed to grasp the OP is struggling with: a simple check:

    $ stat -c %s /proc/$$/status && wc -c < $_
    0
    849
    

    That is, the stat call on a file under /proc shows it has no contents but actually reading from that file returns that contents.

    OK, so the solution is simple: instead of doing a call to os.Stat() while traversing the subtree of the filesystem one should instead merely attempt to read a single byte from the file, like in:

    var buf [1]byte
    f, err := os.Open(fname)
    if err != nil {
        // do something, or maybe ignore.
        // A not existing file is OK to ignore
        // (the POSIX error code will be ENOENT)
        // because after the `path/filepath.Walk()` fetched an entry for
        // this file from its directory, the file might well have gone.
    }
    _, err = f.Read(buf[:])
    if err != nil {
        if err == io.EOF {
            // OK, we failed to read 1 byte, so the file is empty.
        }
        // Otherwise, deal with the error
    }
    f.Close()
    

    You might try to be more clever and first obtain the stat information (using a call to os.Stat()) to see if the file is a regular file—to not attempt reading from sockets etc.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c