从lsof中拉取字段/属性(Linux命令行)

时间:2011-02-21 00:58:27

标签: linux bash command-line flv

随着最近转向Flash 10(或者它可能是一个发行版选择),我和其他许多人不再能够从/ tmp复制Flash视频。但是,我在下面找到了一个解决方法:

首先,执行:

lsof | grep Flash

应返回如下输出:

plugin-co 8935    richard   16w      REG        8,1   4139180       8220 /tmp/FlashXXq4KyOZ (deleted)

注意:您可以在此处看到问题.... / tmp文件已释放文件指针。

但是,您可以通过使用cp命令来获取文件:

cp /proc/#/fd/# video.flv

其中第一个#是进程ID(8935),第二个是下一个数字(16,从16w开始)。

目前,这有效,但需要一些手动步骤。为了自动化,我想我可以拉动PID和fd号并将它们动态插入到cp命令中。

我的问题是如何将适当的字段拉入变量?我知道您可以使用$ 1等来获取输入参数,但是如何检索输出?

注意:我可以使用pidof plugin-container来查找PID,但我仍然需要另一个数字(因为它告诉要保存哪个特定的Flash视频)。

4 个答案:

答案 0 :(得分:5)

以下命令将返回/tmp中文件名以“Flash”开头的所有文件的PID和FD

lsof -F pfn /tmp/Flash*

,输出看起来像这样:

p16471
f16
n/tmp/FlashXXq4KyOZ
f17
n/tmp/FlashXXq4KyOZ
p26588
f16
n/tmp/FlashYYh3JwIW
f17

字段标识符为p:PID,f:FD,n:NAME。 -F选项旨在使lsof的输出易于解析。

迭代这些并删除字段标识符是微不足道的。

#!/bin/bash
c=-1
while read -r line
do
    case $line in
        f*)
            fds[pids[c]]+=${line:1}" "
            ;;
        n*)
            names[pids[c]]+=${line:1}" "
            ;;
        p*)
            pids[++c]=${line:1}
            ;;
    esac
done < <(lsof -F pfn -- /tmp/Flash*)

for ((i=0; i<=c; i++))
do
    for name in ${names[pids[i]]}
    do
        for fd in ${fds[pids[i]]}
        do
            echo "File: $name, Process ID: ${pids[i]}, File Descriptor: $fd"
        done
    done
done

这样的行:

fds[pids[c]]+=${line:1}" "

在存储在由PID索引的数组中的字符串中累积文件描述符。对于包含空格的文件名,对文件名执行此操作将失败。如有必要,可以解决这个问题。

使用子字符串运算符剥离行的前导字段描述符:${line:1}从第一个位置开始,包含字符串的其余部分,使字符为零。

第二个循环只是一个演示迭代数组的演示。

答案 1 :(得分:2)

var=$(lsof | awk '/Flash/{gsub(/[^0-9]/,"",$4);print $2 FS $4};exit')
set -- $var
pid=$1
number=$2

答案 2 :(得分:1)

完成的脚本:

#!/bin/sh

if [ $1 ]; then
    #lsof | grep Flash | awk '{print $2}' also works for PID
    pid=$(pidof plugin-container)
    file_num=$(lsof -p $pid | grep /tmp/Flash | awk '{print substr($4,1,2)}')

    cp /proc/$pid/fd/$file_num ~/Downloads/"$1".flv
else
    echo "Please enter video name as argument."
fi

答案 3 :(得分:0)

避免使用lsof,因为返回路径需要太长时间(> 30秒)。下面的.bashrc行将与vlc,mplayer或其他任何内容一起使用,并以毫秒为单位返回已删除临时文件的路径。

flashplay () {
          vlc $(stat -c %N /proc/*/fd/* 2>&1|awk -F[\`\'] '/lash/{print$2}')
}