淡泊以明志,寜靜以致遠

密碼登陸太麻煩了,使用密鑰簡單。更安全?也許。
生成密鑰,依提示來做。
ssh-keygen

在~/.ssh目錄得到兩個文件(密鑰對)

id_rsa id_rsa.pub

其中,.pub是公鑰,另外一個是私鑰。

公鑰放服務器上

ssh-copy-id -i id_rsa.pub user@foo.fffo.com
完成上面命令後,會在服務器的~/.ssh下發現文件authorized_keys,內含id_rsa.pub之內容

私鑰放本地,權限為600,否則登陸可能會出現類似下面的提示。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for ‘/home/ewrwer/.ssh/id_rsa’ are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /home/ewrwer/.ssh/id_rsa
ewrwer@fewrwrw’s password:

本地配置~/.ssh/config內容類似下面

Host HostA
HostName HostA.domain.net
User useratA
IdentityFile ~/.ssh/id_rsa.HostA

Host HostB
HostName HostB.domain.net
User useratB
IdentityFile ~/.ssh/id_rsa.HostB

然後就可以通過下面命令來登陸ssh了。
ssh HostA

參考資料:

以通知方式显示论坛最近回复主题/新主题
测试地址 http://forum.ubuntu.org.cn/viewforum.php?f=21
因为是最近回复/新主题,所以把年份和日期去掉,只保留时间.在合并数据时遇到麻烦,数据行数相同的情况下,卻把第二组数据添加到第一组数据相应的行末,像vim里的 Ctrl+V 的块选择模式一样,把后面的数据以块形式直接添加到前面来.或者可以把这个问题描述为: 在第一组数据各行末添加第二组数据
在想不到其它办法的情况下,我只好通过下面的方法来.
输出第一组数据第1行到文件line1.dat,追加第二组数据第1行到文件line1.dat(把换行符\n替换成034)
034为ASCII中以八进制记录的字符034
重复,直到最后数据读完.
这样得到line[1-5].dat五个文件.

cat line?.dat
shell脚本可以在...
name'034'请教shell排序问...
name'034'初学者写脚本,高手指...
name'034'find 查找一个随...
name'034'这是我的vsftpd...
name'034'

合并文件,把034替换成换行符\n

通知显示文本格式如下
title(取前十个字符)…作者@时间

shell脚本可以在…name@14:36
请教shell排序问…name@12:46
初学者写脚本,高手指…name@12:24
find 查找一个随…name@11:36
这是我的vsftpd…name@0:04

#!/bin/zsh
old=''
cd /tmp/test
while :
do
curl -s "http://forum.ubuntu.org.cn/viewforum.php?f=21" 2>/dev/null >forum.dat
data=`cat forum.dat`
title=`echo "$data" | grep -oP '[^ ]*topictitle.*' | perl -pe 's|.*title"\>(.*?)\<\/a>.*|\1|' | sed -n '6,$p' | head -5 | sed -r 's/^(.{10}).*/\1\.../'`
name=`echo $data | grep 'class="topicdetails"><a'|perl -pe 's|.*\>(.*?)\<.*|\1|' | sed -n '6,$p' | head -5`
last=`echo $data | grep '"topicdetails" style'|perl -pe 's|.*\>(.*?)\<.*|\1|' | sed '1~2d' | sed -n '6,$p' | head -5 | awk '{print "@"$2}'`
for i in {1..5};do echo $title |sed -n "${i}p">line$i.dat;echo $name | sed -n "${i}p" |tr '\n' '\034' >>line$i.dat;done;
titlename=`cat line?.dat | tr -d '\n'|tr '\034' '\n'`
for i in {1..5};do echo ${titlename} |sed -n "${i}p">line$i.dat;echo $last | sed -n "${i}p" |tr '\n' '\034' >>line$i.dat;done;
new=`cat line?.dat | tr -d '\n'|tr '\034' '\n'`
[ "$new" = "$old" ] || notify-send "$new"
old=$new
sleep 300
done

最近完成版本

#!/bin/bash
[ -f ~/.forumstatus.dat ] || touch ~/.forumstatus.dat
old=`cat ~/.forumstatus.dat`
[ -d /tmp/forumshell ] || mkdir /tmp/forumshell
cd /tmp/forumshell
while : ; do
curl -s "http://forum.ubuntu.org.cn/viewforum.php?f=21" 2>/dev/null >forum.dat
delnum=$(expr $(grep -cP 'styles\/.*\/imageset\/announce_.*' forum.dat )  + $(grep -cP 'styles\/.*\/imageset\/sticky_.*' forum.dat ) - 2)
shownum=5
begin=`expr $delnum + 1`
end=`expr $delnum + $shownum`
sed -rn 's/.*"topictitle">(.{1,10}).*<\/a>.*/\1\.../p' forum.dat | sed -n "$begin,$end"p > title.dat
sed -nr 's/.*class="topicdetails"><.*>(.*)<\/a>$/\1/p' forum.dat | sed -n "$begin,$end"p  >name.dat
sed -nr 's/.*"topicdetails" style.* (.*)<\/p>/@\1/p' forum.dat |  sed '1~2d' | sed -n "$begin,$end"p  >last.dat
new=`paste title.dat name.dat last.dat |tr -d '\t'`
[ "$new" = "$old" ] || notify-send "$new"
old="$new"
echo "$old" >~/.forumstatus.dat
sleep 300
done

<<< 可以不使用变量。

#!/bin/bash
# 能不能先并行(使用一个没有出现过特殊字符串作为结束标记),再分行?
# file1.txt
#"abcxdefgaxcdyeafgxyxabefght..."
#"fewewretgjkjk543yeafgxy4534ght..."
# 处理 删除第一个x前的内容和最后一个y后面的内容
# 预期结果 
#defgaxcdyeafgxyxabefght..."
#"fewewretgjkjk543yeafgx         
# 合并行 
# "公平"就是传说中的标记
sed 's/$/公平/g' tex1.txt | tr -d '\n' | sed 's/公平$//'>file1.txt
i=`sed 's/x.*$/x/' file1.txt`
j=`sed 's/^.*y/y/' file1.txt`
echo $i $j | sed -e "s/$i//" -e "s/$j$//" file1.txt | sed 's/公平/\n/g' 

几经修改,最后得到是代码是下面几行。算法不变:先并行,再行分,使用贪婪匹配 x.*y

#!/bin/bash
for i in text*.txt
do
cat $i | tr '\n' '\034' | grep -oP 'x.*y' | sed -e 's/^x//;s/y$//' | tr '\034' '\n' | tee out-$i
done
exit 0

添加了几行代码,以便在使用xterm执行这个脚本时,显示当前曲目。
添加在函数 ShowLyric() 和下载函数 “# 两种方式都搜索不到”之后

GetInfo;
echo -ne "33]0;$SONG-$ARTIST07"

代码合并,两个文件管理起来麻烦,所以就合并了。
在启动时可以这样
代码:
xterm -e "foo.sh"
对xterm启动参数进行具体设定。
xterm -bg "#e0e0ef" -fg "#a00fcf" -geometry 37x4+1092+202 -e "/media/Dropbox/lyric4deadbeef/db.sh"

然后,就会显示当前播放曲目在标题了。
就不上图了。麻烦。


#!/bin/bash
######  include functions                              
######  Getstatus() GetInfo()  ShowLyric() Download() Wait()

# modified from mpdlyric by wiewi,lwldcr@gmail.com
# Show lyric when playing music with deadbeef
# 2011/07/17
# contributor wiewi,lwldcr@gmail.com
# 2011/08/06
# modified by Danny Chow, xizhengbing \A\T gmail.com
# Download function!!
# Finished on July 20,Wednesday
# Last modifed August 7,Sunday

Getstatus(){
before=$(deadbeef --nowplaying  %e 2>/dev/null)
after=$(sleep 1;deadbeef --nowplaying  %e 2>/dev/null)
[ $before != $after ] && STATUS="playing"
echo $STATUS
}

GetInfo(){
# Song info
SONG=$(deadbeef --nowplaying %t 2>/dev/null)
ARTIST=$(deadbeef --nowplaying %a 2>/dev/null)
NAME=$SONG
# LRC file
FILE=$LYRIC/`echo $NAME | tr -d ' '`.lrc
}

Download(){
    # 从gougou搜索歌词文件并下载
    #gougou will lead to the site used below

    GetInfo;

    PERIOD=''
    [ -f "$SEARCH" ] && rm -f $SEARCH

    # “歌曲名 歌手” 搜索  管道写法参考lrcdis脚本
    wget -c -T 10 "http://www.lrc123.com/?keyword=$NAME $ARTIST&" -O $SEARCH > /dev/null 2>&1 |  iconv -f GBK

    URL=`cat $SEARCH | grep -B1 '下载' | grep color | sed -n '1p'| sed 's/<[^>]*>//g' | tr -d ' '|sed 's/\\r//'`

    # 第一种方式搜索不到,使用“歌曲名” 搜索
    if [ -z "$URL" ];then
        wget -c -T 10 "http://www.lrc123.com/?keyword=$NAME&" -O $SEARCH > /dev/null 2>&1 | iconv -f GBK
    fi
    URL=`cat $SEARCH | grep -B1 '下载' | grep color | sed -n '1p'| sed 's/<[^>]*>//g' | tr -d ' '|sed 's/\\r//'`

    if [ -z "$URL" ];then
    # 两种方式都搜索不到
        echo "LRC not found!" # &&  exit 1
        GetInfo;
        echo -ne "\033]0;$SONG-$ARTIST\007"
        SONG_PREV=$(deadbeef --nowplaying %t 2>/dev/null)
        Wait;

    else
    # 有搜索结果,那么下载歌词文件
        wget -c -T 10 $URL -O "$FILE" > /dev/null 2>&1| iconv -f GBK
    fi

}

Wait(){
    # 对于下载不到歌词的曲目,每隔1秒重新读取播放器信息,一旦切换到下首,则重新尝试Download歌词
while :
do
   sleep 1
   GetInfo
   if [ "$SONG_PREV" != "$SONG" ];then
       SONG_PREV=$SONG
       [ -f "$FILE" ] || Download;
       ShowLyric;
   fi
done
}
ShowLyric(){
#       [ -f "$FILE" ] || Download;
       #eval "$CMD" "\n$NAME - $ARTIST\n"
       GetInfo;
       echo -ne "\033]0;$SONG-$ARTIST\007"
       echo -e "\n$NAME - $ARTIST\n"
       notify-send "$NAME - $ARTIST"
       while :
       do
       if [ ! "`file $FILE | grep -i utf-8`" ];then
            iconv -f GBK -t UTF-8 $FILE -o $FILE
       fi
       TIME=$(deadbeef --nowplaying %e 2>/dev/null)
       TEXT=$(cat "$FILE" | grep $TIME | sed 's/\[[^]]*]//g')
       CURRENT=$(deadbeef --nowplaying %t 2>/dev/null)

       if [ -z "$PREV" -o "$CURRENT" = "$PREV" ];then
         PREV=$CURRENT

         # 换到下一句歌词
         if [ -n "$TEXT" -a "$TEXT" != "$TEXT_PREV" ];then
# Notify 方式有问题,歌词更新太慢,即使指定了timeout问题依旧
#       notify-send -t $TIMEOUT -- "$TEXT"
#              echo $TEXT
              sleep 0.8
              eval "$CMD"
              TEXT_PREV="$TEXT"
         fi
       # 歌曲切换
       else
              PREV=''
              GetInfo
             # eval "$CMD" "\n$NAME - $ARTIST\n"
              echo -ne "\033]0;$SONG-$ARTIST\007"
              echo -e "\n$NAME - $ARTIST\n"
              notify-send "$NAME - $ARTIST"

              [ -f "$FILE" ] || Download;
              continue
       fi
         sleep 0.3
       done
}
# Lyric dir
 [ -d $HOME/.lyrics ] || mkdir $HOME/.lyrics -v

LYRIC=$HOME/.lyrics

# Temp files
[ -d $HOME/tmp ] || mkdir $HOME/tmp -v
SEARCH=$HOME/tmp/search

# Notify timeout
TIMEOUT=1000
case $1 in
    -n) CMD='notify-send -t $TIMEOUT --  $TEXT'
        ;;
    *)  CMD='echo $TEXT'
        ;;
esac

Getstatus
while :
do
case $STATUS in
    playing) GetInfo
             [ -f "$FILE" ] || Download;
             ShowLyric;;
    *) echo "Deadbeef is not running!" && exit 1;;
esac
done

参考资料 如何變更 xterm 的主題

修改自 http://forum.ubuntu.org.cn/viewtopic.php?f=21&t=339043 1楼 感谢wiewi
为简洁起见,我把主体和函数分开了。
我只是修改很少的一部分。函数我还没看完呢。:-(
比较难的可能是如何获取播放状态吧。
下面是 Deadbeef music player 的一个问题。

I haven’t looked at DeaDBeeF’s command line options, but is there one that will output its status? Then you’d just need a script with an if conditional:

!#/bin/bash
if `deadbeef –state` = “PLAY” #replace this with whatever code is necessary to find out if DeaDBeeF is playing
deadbeef –pause
else
deadbeef –play
endif

…and that’s your play/pause toggle.

我自己想办法解决了。

Chow Daniel
我真是笨啊。檢查播放狀態不一定要直接從程序給出的命令行中得出​。如果1秒前的播放位置和現在不同,那麽它就是“正在播放”
about an hour ago ·

主体部分
文件名 lyric4deadbeef.sh

#!/bin/bash
# modified from mpdlyric by wiewi,lwldcr@gmail.com
# Show lyric when playing music with deadbeef
# 2011/07/17
# contributor wiewi,lwldcr@gmail.com
# 2011/08/06
# modified by Danny Chow, xizhengbing \A\Tgmail.com
# Download function!! 
# Finished on July 20,Wednesday
# Last modifed August 6,Saturday
. functions.main
# Lyric dir
 [ -d $HOME/.lyrics ] || mkdir $HOME/.lyrics -v

LYRIC=$HOME/.lyrics

# Temp files
[ -d $HOME/tmp ] || mkdir $HOME/tmp -v
SEARCH=$HOME/tmp/search

# Notify timeout
TIMEOUT=1000
case $1 in
    -n) CMD='notify-send -t $TIMEOUT --  $TEXT'
        ;;
    *)  CMD='echo $TEXT'
        ;;
esac

Getstatus
while :
do
case $STATUS in
    playing) GetInfo
             [ -f "$FILE" ] || Download;
             ShowLyric;;
    *) echo "Deadbeef is not running!" && exit 1;;
esac
done

函数部分
文件名 functions.main

#!/bin/bash
# functions for lyric4deadbeef

######	include functions										###### 
######	Getstatus() GetInfo()  ShowLyric() Download() Wait()	###### 

# modified from mpdlyric by wiewi,lwldcr@gmail.com
# Show lyric when playing music with deadbeef
# 2011/07/17
# contributor wiewi,lwldcr@gmail.com
# 2011/08/06
# modified by Danny Chow, xizhengbing \A\T gmail.com
# Download function!! 
# Finished on July 20,Wednesday
# Last modifed August 6,Saturday
Getstatus(){
before=$(deadbeef --nowplaying  %e 2>/dev/null)
after=$(sleep 1;deadbeef --nowplaying  %e 2>/dev/null)
[ $before != $after ] && STATUS="playing"
echo $STATUS
}
GetInfo(){

# Song info
SONG=$(deadbeef --nowplaying %t 2>/dev/null)
ARTIST=$(deadbeef --nowplaying %a 2>/dev/null)
NAME=$SONG

# LRC file
FILE=$LYRIC/`echo $NAME | tr -d ' '`.lrc
}

Download(){
    # 从gougou搜索歌词文件并下载
    #gougou will lead to the site used below

    GetInfo;

    PERIOD=''
    [ -f "$SEARCH" ] && rm -f $SEARCH

    # “歌曲名 歌手” 搜索  管道写法参考lrcdis脚本
    wget -c -T 10 "http://www.lrc123.com/?keyword=$NAME $ARTIST&" -O $SEARCH > /dev/null 2>&1 |  iconv -f GBK

    URL=`cat $SEARCH | grep -B1 '下载' | grep color | sed -n '1p'| sed 's/<[^>]*>//g' | tr -d ' '|sed 's/\\r//'`

    # 第一种方式搜索不到,使用“歌曲名” 搜索
    if [ -z "$URL" ];then
        wget -c -T 10 "http://www.lrc123.com/?keyword=$NAME&" -O $SEARCH > /dev/null 2>&1 | iconv -f GBK
    fi
    URL=`cat $SEARCH | grep -B1 '下载' | grep color | sed -n '1p'| sed 's/<[^>]*>//g' | tr -d ' '|sed 's/\\r//'`

    if [ -z "$URL" ];then
    # 两种方式都搜索不到
        echo "LRC not found!" # &&  exit 1
        SONG_PREV=$(deadbeef --nowplaying %t 2>/dev/null)
        Wait;

    else
    # 有搜索结果,那么下载歌词文件
        wget -c -T 10 $URL -O "$FILE" > /dev/null 2>&1| iconv -f GBK
    fi

}

Wait(){
    # 对于下载不到歌词的曲目,每隔1秒重新读取播放器信息,一旦切换到下首,则重新尝试Download歌词
while :
do
   sleep 1
   GetInfo
   if [ "$SONG_PREV" != "$SONG" ];then
       SONG_PREV=$SONG
       [ -f "$FILE" ] || Download;
       ShowLyric;
   fi
done
}
ShowLyric(){
#       [ -f "$FILE" ] || Download;
       #eval "$CMD" "\n$NAME - $ARTIST\n"
       echo -e "\n$NAME - $ARTIST\n"
       notify-send "$NAME - $ARTIST"
       while :
       do
       if [ ! "`file $FILE | grep -i utf-8`" ];then
            iconv -f GBK -t UTF-8 $FILE -o $FILE
       fi
       TIME=$(deadbeef --nowplaying %e 2>/dev/null)
       TEXT=$(cat "$FILE" | grep $TIME | sed 's/\[[^]]*]//g')
       CURRENT=$(deadbeef --nowplaying %t 2>/dev/null)

       if [ -z "$PREV" -o "$CURRENT" = "$PREV" ];then
         PREV=$CURRENT

         # 换到下一句歌词
         if [ -n "$TEXT" -a "$TEXT" != "$TEXT_PREV" ];then
# Notify 方式有问题,歌词更新太慢,即使指定了timeout问题依旧
#       notify-send -t $TIMEOUT -- "$TEXT"
#              echo $TEXT
              sleep 0.8
              eval "$CMD"
              TEXT_PREV="$TEXT"
         fi
       # 歌曲切换
       else
              PREV=''
              GetInfo
             # eval "$CMD" "\n$NAME - $ARTIST\n"
              echo -e "\n$NAME - $ARTIST\n"
              notify-send "$NAME - $ARTIST"

              [ -f "$FILE" ] || Download;
              continue
       fi
         sleep 0.3
       done
}

时间紧,暂时到此。水平有限,可能修改得不够好。

使用办法
把前面的代码保存为 lyric4deadbeef.sh 或者你喜欢的名字
后面的代码保存为 functions.main (和 lyric4deadbeef.sh同一个目录下)
然后

chmod +x  lyric4deadbeef.sh  functions.main

当然,不想分开也是可以的。把函数部分并在lyric4deadbeef.sh中的 #!/bin/bash 后面,去掉行 . functions.main

fceux/xmame 这两个的特点都是使用SDL引擎。
本人目前使用的声音架构是ALSA+puleaudio
我在~/.zshrc里配置了以下内容。

export SDL_AUDIODRIVER=dsp

设定使用/dev/dsp,结果找不到设备,搜索。找到解决之道。要添加模块snd-pcm-oss, 默认没有添加
在/etc/rc.conf载入模块设定里添加snd-pcm-oss,修改后的内容为

MODULES=(fuse snd-pcm-oss !usblp)

立即生效的做法

modprobe snd-pcm-oss

参考资料: http://wiki.debian.org/SoundFAQ

Error: audio: /dev/dsp: No such file or directory

If the audio mixer application is reporting that no mixer is available, or gives an error:

audio: /dev/dsp: No such file or directory

It is necessary to load the snd-pcm-oss module.

本来的问题不是”替换指定多行关键词” 这么抽象的。本来的问题是:注释含有关键词 “foo” 的行, 注释符是 %
经过本人的思考,就转化变成前面的问题。
在百度里也有人提过这个问题,可惜问题关闭了。

用vi命令替换1到10行,或者替换当前行到某行,这个都会,但是如果我想要替换1-10行,18,20行,这样怎么写?

下面是实现代码

for i in  `grep -n 'foo' foo.ps | awk -F ":" '{print $1}'`;
do echo $i|sed -i "${i}s/^/%/" foo.ps ;done

解释一下

  • for i in ;do ;done 经典的for 循环
  • grep -n ‘foo’ foo.ps | awk -F “:” ‘{print $1}’ 获取关键词所在行号
  • echo $i|sed -i “${i}s/^/%/” 传递shell变量给sed, 并替换指定行$i 的关键词^(行首)为%(注释)

代码虽短,但并不意味着写出这段代码容易和省时间。
目前只知道种方法,至于其它方法,God knows.

关注

每发布一篇新博文的同时向您的邮箱发送备份。