随着最近转向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视频)。
答案 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}')
}