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

发布于 2024-10-18 07:55:24 字数 678 浏览 8 评论 0原文

随着最近迁移到 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 视频)。

With the recent move to Flash 10 (or maybe it was a distro choice), I and many others are no longer able to copy Flash videos from /tmp. I have, however, found a workaround in the following:

First, execute:

lsof | grep Flash

which should return output like this:

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

Note: You can see the problem here....the /tmp file has the file pointer released.

You are, however, able to grab the file by using the cp command thusly:

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

where the 1st # is the process ID (8935) and the second if the next number (16, from 16w).

Currently, this works, but it requires a few manual steps. To automate this, I figure I could pull the PID and the fd number and insert them dynamically into the cp command.

My question is how do I pull the appropriate fields into variables? I know you can use $1, etc. for grabbing input arguments, but how do you retrieve outputs?

Note: I could use pidof plugin-container to find the PID, but I still need the other number (since it tells which specific flash video to save).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

生活了然无味 2024-10-25 07:55:25

以下命令将返回 /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:姓名。 -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} 从位置一开始并包含字符串的其余部分,因此它会删除字符零。

第二个循环只是一个演示,用于展示对数组的迭代。

The following command will return PIDs and FDs for all the files in /tmp that have filenames that begin with "Flash"

lsof -F pfn /tmp/Flash*

and the output will look something like this:

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

Where the field identifiers are p: PID, f: FD, n: NAME. The -F option is designed to make the output of lsof easy to parse.

Iterating over these and removing the field identifiers is trivial.

#!/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

Lines like this:

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

accumulate file descriptors in a string stored in an array indexed by the PID. Doing this for file names will fail for filenames which contain spaces. That could be worked around if necessary.

The line is stripped of the leading field descriptor character by using a substring operator: ${line:1} starts at position one and includes the rest of the string so it drops character zero.

The second loop is just a demo to show iterating over the arrays.

伪心 2024-10-25 07:55:25
var=$(lsof | awk '/Flash/{gsub(/[^0-9]/,"",$4);print $2 FS $4};exit')
set -- $var
pid=$1
number=$2
var=$(lsof | awk '/Flash/{gsub(/[^0-9]/,"",$4);print $2 FS $4};exit')
set -- $var
pid=$1
number=$2
ゝ杯具 2024-10-25 07:55:25

已完成的脚本:

#!/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

Completed Script:

#!/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
香草可樂 2024-10-25 07:55:25

避免使用 lsof,因为返回路径需要很长时间(>30 秒)。下面的 .bashrc 行将与 vlc、mplayer 或您输入的任何内容一起使用,并在几毫秒内返回已删除临时文件的路径。
<代码>

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

Avoid using lsof because it takes too long (>30 seconds) to return the path. The below .bashrc line will work with vlc, mplayer, or whatever you put in and return the path to the deleted temp file in milliseconds.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文