shell脚本中$ {#PIDS}的含义

时间:2011-10-04 17:53:47

标签: bash shell

我正在尝试理解shell脚本。以下脚本只是大脚本的一小部分

#!/bin/sh
for i in `pgrep -f libflashplayer.so`
do
  PIDS=$PIDS$i","
done
echo ${#PIDS}
PIDS=`echo ${PIDS:0:${#PIDS}-1}`

我不清楚

是什么
echo ${#PIDS}
PIDS=`echo ${PIDS:0:${#PIDS}-1}`
上面脚本中的

是什么意思?

**更新**

了解下面的回复后 这是输入

#npviewer. 2768 deel   11u   REG                7,0 19218930   262562 /tmp/FlashXX2j3xhT (deleted)
#npviewer. 2768 deel   12u   REG                7,0 32352982   262837 /tmp/FlashXX6R4nAq (deleted)
#npviewer. 2768 deel   17u   REG                7,0 27289825   262824 /tmp/FlashXXuVBqbu (deleted)
#npviewer. 2768 deel   18u   REG                7,0 21632133   262825 /tmp/FlashXXneoS8s (deleted)

此输入在以下脚本

上给出
for i in `lsof -np $PIDS | grep deleted | grep /tmp/Fl*`
do
     PID=`echo $i | cut -d " " -f 2`
     FD=`echo $i | cut -d " " -f 6`
     FD=`echo ${FD:0:${#FD}-1}`
     echo $FD
done

输出

11u
12u
17u
18

根据我的理解,输出应该是

11
12
17
18

那为什么不是这样呢?

2 个答案:

答案 0 :(得分:3)

Bash reference manual中搜索“$ {#”:

  

${#parameter}

     

扩展值的字符长度   参数已被替换。如果参数*@,则为值   取代的是位置参数的数量。如果参数是   数组名称由*@订阅,替换值为   数组中的元素数量。

答案 1 :(得分:2)

它计算PIDS字符串中的字符数,然后修剪字符串末尾的最后一个逗号。

# cat a.sh
#!/bin/bash

PIDS="1,2,3,4,5,"

echo "${PIDS}"
echo ${#PIDS}
echo "${PIDS:0:${#PIDS}-1}"
# ./a.sh
1,2,3,4,5,
10
1,2,3,4,5

在回复您的更新时,您的输出对我来说有点奇怪。难道你不应该在第二个“剪切”中显示令牌4而不是6吗?除非我误解你的输入数据。这就是我得到的:

# cat a.dat
#npviewer. 2768 deel   11u   REG                7,0 19218930   262562 /tmp/FlashXX2j3xhT (deleted) 
#npviewer. 2768 deel   12u   REG                7,0 32352982   262837 /tmp/FlashXX6R4nAq (deleted) 
#npviewer. 2768 deel   17u   REG                7,0 27289825   262824 /tmp/FlashXXuVBqbu (deleted) 
#npviewer. 2768 deel   18u   REG                7,0 21632133   262825 /tmp/FlashXXneoS8s (deleted) 
# cat a.sh
#!/bin/bash

while read i; do
  PID=`echo $i | cut -d " " -f 2`
  FD=`echo $i | cut -d " " -f 4`  
  FD=`echo ${FD:0:${#FD}-1}`
  echo $FD
done < a.dat

# ./a.sh
11
12
17
18

好的,现在我得到了你正在问的问题,因为我之前在Solaris盒子上,而且我现在在Linux机器上,我得到了不同的结果。所以我想确切的语法可能会有所不同,具体取决于你所使用的shell /平台。

但我确实让我在运行Firefox的Linux机器上工作。不同的是,在我的配置上,无论我打开多少个窗口或标签,它仍然属于相同的进程ID(我正在使用Firefox 3.6运行Xubuntu)。忽略这一点,我们仍然可以通过一次运行一个进程并为每次迭代提取文件描述符来做你想要做的事情。见下面的例子:

user@host:~$ cat a
for p in `pgrep -f libflashplayer.so`
do
  for f in `lsof -p $p | grep tmp/Fl | cut -d " " -f 6 | while read fd; do echo ${fd%[a-z]}; done`
  do
    echo "cp /proc/${p}/fd/${f} ${HOME}/${p}_${f}.flvdone"
  done
done

user@host:~$ ./a
cp /proc/17492/fd/16 /home/user/17492_16.flvdone
cp /proc/17492/fd/19 /home/user/17492_19.flvdone
cp /proc/17492/fd/20 /home/user/17492_20.flvdone

请注意,我没有包含“delete”grep表达式,因为它不会立即删除我配置下的文件。看看您是否可以修改此脚本以执行您要执行的操作。我无法在我的机器上运行$ {PIDS:0:$ {#PIDS} -1}部分,这就是我切换子串命令以使用“%”运算符的原因。它就是这样的。