<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fwolf's Blog &#187; sed - Fwolf's Blog</title>
	<atom:link href="http://www.fwolf.com/blog/post/tag/sed/feed" rel="self" type="application/rss+xml" />
	<link>http://www.fwolf.com/blog</link>
	<description>随心·随意·随缘·努力～</description>
	<lastBuildDate>Wed, 07 Jul 2010 07:07:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>升级MT dv 3.0主机到php5</title>
		<link>http://www.fwolf.com/blog/post/347</link>
		<comments>http://www.fwolf.com/blog/post/347#comments</comments>
		<pubDate>Wed, 08 Aug 2007 17:02:56 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Hosted]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[MediaTemple]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[sed]]></category>
		<category><![CDATA[suexec]]></category>
		<category><![CDATA[upgrade]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/post/347</guid>
		<description><![CDATA[MT主机dv 3.0上的php默认是4，现在已经是php5时代了，不知道MT什么时候默认给配php5，现阶段官方的方式仍然是由用户自行升级，详细步骤见kb中的Upgrade to PHP5 on (dv) 3.0 Dedicated Virtual Servers。 推荐使用suexec方式，这样每个用户执行cgi使用的都是自己的身份，即安全也便于管理。suexec要求的前提条件有三个，就是用户的主机设置开启如下三个选项： PHP支持打开，安全模式safe_mode关闭。 CGI支持打开。 FastCGI支持打开。 具体步骤说起来也是很简单的，首先把/opt/php51下的php5执行文件拷贝到用户目录下，并设置相应权限： cp /opt/php51/cgi-bin/php5 /var/www/vhosts/&#60;domain&#62;/bin/ cd /var/www/vhosts/&#60;domain&#62;/ chown -R &#60;domain-user&#62;:psacln bin/ 其中&#60;domain&#62;是用户的域名，&#60;domain-user&#62;是用户的ssh/ftp用户名，然后编辑/var/www/vhosts/&#60;domain&#62;/conf/vhost.conf文件，添加如下内容： AddHandler fcgid-script .php .php5 SuexecUserGroup &#60;domain-user&#62; psacln &#60;Directory /var/www/vhosts/&#60;domain&#62;/httpdocs&#62; FCGIWrapper /var/www/vhosts/&#60;domain&#62;/bin/php5 .php FCGIWrapper /var/www/vhosts/&#60;domain&#62;/bin/php5 .php5 Options ExecCGI allow from all &#60;/Directory&#62; 如果是https站点，除了httpdocs换成httpsdocs之外，配置文件名称为vhost_ssl.conf。最后启用设置： /usr/local/psa/admin/sbin/websrvmng -a -v 就可以了，我们主机上现在的php5版本是5.1.4，还是不够新:)。 为了方便操作，自己写了个小脚本： #! /bin/bash # [...]]]></description>
			<content:encoded><![CDATA[<p>MT主机dv 3.0上的php默认是4，现在已经是php5时代了，不知道MT什么时候默认给配php5，现阶段官方的方式仍然是由用户自行升级，详细步骤见<a href="http://kb.mediatemple.net/article.php?id=260">kb中的Upgrade to PHP5 on (dv) 3.0 Dedicated Virtual Servers</a>。</p>

<p>推荐使用suexec方式，这样每个用户执行cgi使用的都是自己的身份，即安全也便于管理。suexec要求的前提条件有三个，就是用户的主机设置开启如下三个选项：</p>

<ul>
<li>PHP支持打开，安全模式safe_mode关闭。</li>
<li>CGI支持打开。</li>
<li>FastCGI支持打开。</li>
</ul>

<p>具体步骤说起来也是很简单的，首先把<code>/opt/php51</code>下的php5执行文件拷贝到用户目录下，并设置相应权限：</p>

<pre><code>cp /opt/php51/cgi-bin/php5 /var/www/vhosts/&lt;domain&gt;/bin/
cd /var/www/vhosts/&lt;domain&gt;/
chown -R &lt;domain-user&gt;:psacln bin/
</code></pre>

<p>其中<code>&lt;domain&gt;</code>是用户的域名，<code>&lt;domain-user&gt;</code>是用户的ssh/ftp用户名，然后编辑<code>/var/www/vhosts/&lt;domain&gt;/conf/vhost.conf</code>文件，添加如下内容：</p>

<pre><code>AddHandler fcgid-script .php .php5
SuexecUserGroup &lt;domain-user&gt; psacln
&lt;Directory /var/www/vhosts/&lt;domain&gt;/httpdocs&gt;
     FCGIWrapper /var/www/vhosts/&lt;domain&gt;/bin/php5 .php
     FCGIWrapper /var/www/vhosts/&lt;domain&gt;/bin/php5 .php5
     Options ExecCGI
     allow from all
&lt;/Directory&gt;
</code></pre>

<p>如果是https站点，除了httpdocs换成httpsdocs之外，配置文件名称为vhost_ssl.conf。最后启用设置：</p>

<pre><code>/usr/local/psa/admin/sbin/websrvmng -a -v
</code></pre>

<p>就可以了，我们主机上现在的php5版本是5.1.4，还是不够新:)。</p>

<p>为了方便操作，自己写了个小脚本：</p>

<pre><code>#! /bin/bash
# Automatic enable php5 support for mediatemple user(via suexec).

# Pre-prepare in plesk:
#   php support is checked, safe_mod 'on' is UNCHECKED
#   cgi support is checked.
#   fastcgi support is checked.

# Check username, must run with root
WHOAMI=`whoami`
if [ ! $WHOAMI == 'root' ]; then
    echo "This script must run with root."
    exit 1
fi

# Check parameters
if [ $# -lt 2 ];then
    echo "Usage: `basename $0` ssh_user domain"
    exit 1
fi
USER=$1
DOMAIN=$2

# If given a wrong domain, exit
if [ ! -d /var/www/vhosts/$DOMAIN ]; then
    echo "Domain doesn't exists."
    exit 1
fi

# Copy php5 files
cp /opt/php51/cgi-bin/php5 /var/www/vhosts/$DOMAIN/bin/
cd /var/www/vhosts/$DOMAIN/
chown -R $USER:psacln bin/
cd conf

BEGIN="###_87b4e7fc -- Add by enable_php script, DON'T modify this section --"
END="# -- Enable_php modify section end -- 87b4e7fc_###"

# If vhost.conf doesn't exists, create it with default content
if [ -z vhost.conf ]; then
    echo "\\
$BEGIN\\
$END\\
" &gt;&gt; vhost.conf
else
    MARK=`grep "###_87b4e7fc" vhost.conf|wc -l`
    if [ $MARK -eq 0 ]; then
        # If vhost.conf exists &amp; not mark, add replace mark
        echo "\\
$BEGIN\\
$END\\
" &gt;&gt; vhost.conf
    fi
fi
# Vhost_ssl.conf
if [ -z vhost_ssl.conf ]; then
    echo "\\
$BEGIN\\
$END\\
" &gt;&gt; vhost_ssl.conf
else
    MARK=`grep "###_87b4e7fc" vhost_ssl.conf|wc -l`
    if [ $MARK -eq 0 ]; then
        # If vhost.conf exists &amp; not mark, add replace mark
        echo "\\
$BEGIN\\
$END\\
" &gt;&gt; vhost_ssl.conf
    fi
fi


STR="$BEGIN\\n\\
AddHandler fcgid-script .php .php5\\n\\
SuexecUserGroup $USER psacln\\n\\
&lt;Directory \\/var\\/www\\/vhosts\\/$DOMAIN\\/httpdocs&gt;\\n\\
    FCGIWrapper \\/var\\/www\\/vhosts\\/$DOMAIN\\/bin\\/php5 .php\\n\\
    FCGIWrapper \\/var\\/www\\/vhosts\\/$DOMAIN\\/bin\\/php5 .php5\\n\\
    Options \\+ExecCGI\\n\\
    allow from all\\n\\
&lt;\\/Directory&gt;\\n\\
&lt;Directory \\/var\\/www\\/vhosts\\/$DOMAIN\\/httpsdocs&gt;\\n\\
    FCGIWrapper \\/var\\/www\\/vhosts\\/$DOMAIN\\/bin\\/php5 .php\\n\\
    FCGIWrapper \\/var\\/www\\/vhosts\\/$DOMAIN\\/bin\\/php5 .php5\\n\\
    Options \\+ExecCGI\\n\\
    allow from all\\n\\
&lt;\\/Directory&gt;\\n\\
$END"

# Backup original configure
cp vhost.conf vhost.conf.`date +"%Y%m%d-%H%M%S"`
cp vhost_ssl.conf vhost_ssl.conf.`date +"%Y%m%d-%H%M%S"`

# Write configure information
sed -i -e ":begin; /###_87b4e7fc/,/87b4e7fc_###/ { /87b4e7fc_###/! { $! { N; b begin }; }; s/###_87b4e7fc.*87b4e7fc_###/$STR/g };" vhost.conf
sed -i -e ":begin; /###_87b4e7fc/,/87b4e7fc_###/ { /87b4e7fc_###/! { $! { N; b begin }; }; s/###_87b4e7fc.*87b4e7fc_###/$STR/g };" vhost_ssl.conf

# Active new configure
/usr/local/psa/admin/sbin/websrvmng -a -v
</code></pre>

<p>使用方法，用root用户执行：</p>

<pre><code>enable_php5 &lt;domain-user&gt; &lt;domain&gt;
</code></pre>

<p>不支持subdomain的设置，其中sed替换多行内容的用法，可以参考我写的另外一篇文章<a href="346">用sed替换跨行内容</a>。</p>

<p>conf/vhost.conf这个文件存在之后，并不会自动被apache调用，执行<code>/usr/local/psa/admin/sbin/websrvmng -a -v</code>可以自动在<code>conf/httpd.include</code>文件中include vhost.conf了。而<code>conf/httpd.include</code>这个文件是由plesk维护的，用户不要直接修改它，会被plesk覆盖掉。</p>

<p>另外由于使用的是suexec方式执行，所以上传目录、cache等以前需要设置apache用户有可写权限的文件，现在要把owner设置为<code>&lt;domain-user&gt;:psacln</code>才行，和用户的其他文件权限一样就可以了，是不是管理起来更方便一些？</p>

<p>看了一下phpinfo，自动加载了位于<code>/opt/php51/lib/php5/extensions/</code>下的如下模块：</p>

<pre><code>curl.so  gd.so        mysql.so    pdo.so        sockets.so  zlib.so
dom.so   iconv.so     mysqli.so   pdo_mysql.so  sqlite.so
ftp.so   mbstring.so  openssl.so  posix.so      xsl.so
</code></pre>

<p>基本上常用的都有了，但不知道<code>/opt/php51</code>这个目录下的内容MT什么时候给更新，还是说需要用户自己更新？</p>

<h4>参考</h4>

<ul>
<li><a href="http://www.v2ex.com/topic/view/13732.html">(mt) (dv) 3.0 入门</a></li>
</ul>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/apache" title="Apache" rel="tag">Apache</a>, <a href="http://www.fwolf.com/blog/post/tag/bash" title="bash" rel="tag">bash</a>, <a href="http://www.fwolf.com/blog/post/tag/fastcgi" title="FastCGI" rel="tag">FastCGI</a>, <a href="http://www.fwolf.com/blog/post/tag/mediatemple" title="MediaTemple" rel="tag">MediaTemple</a>, <a href="http://www.fwolf.com/blog/post/tag/php" title="PHP" rel="tag">PHP</a>, <a href="http://www.fwolf.com/blog/post/tag/sed" title="sed" rel="tag">sed</a>, <a href="http://www.fwolf.com/blog/post/tag/suexec" title="suexec" rel="tag">suexec</a>, <a href="http://www.fwolf.com/blog/post/tag/upgrade" title="upgrade" rel="tag">upgrade</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/411" title="由一个错误学到的一些php安全配置问题 (2008-07-13)">由一个错误学到的一些php安全配置问题</a> (4)</li>
	<li><a href="http://www.fwolf.com/blog/post/412" title="[MediaTemple]从(dv)3.0升级到3.5 (2008-07-13)">[MediaTemple]从(dv)3.0升级到3.5</a> (1)</li>
	<li><a href="http://www.fwolf.com/blog/post/443" title="配置安全的共享web服务器（抛砖引玉） (2009-06-09)">配置安全的共享web服务器（抛砖引玉）</a> (4)</li>
	<li><a href="http://www.fwolf.com/blog/post/407" title="生成用于web服务器的openssl证书 (2008-06-25)">生成用于web服务器的openssl证书</a> (1)</li>
	<li><a href="http://www.fwolf.com/blog/post/127" title="利用SVN更新网站 (2006-01-19)">利用SVN更新网站</a> (7)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/347/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>用sed替换跨行内容</title>
		<link>http://www.fwolf.com/blog/post/346</link>
		<comments>http://www.fwolf.com/blog/post/346#comments</comments>
		<pubDate>Wed, 08 Aug 2007 14:27:27 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[sed]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/post/346</guid>
		<description><![CDATA[sed是*nix下方便的行编辑工具，经常用来替换文件的内容，sed一般都是处理单行的，但通过它的一些内建功能，也能实现跨行替换（即要替换的内容有多行内容）。 解决方法主要来自网上搜到的一篇文章，但文中的大侠并没有解释得特别清楚，我对照着其他两个更晦涩的例子（一、二），结合man搞懂了之后，记录于此。 假设我们的目标文件test内容是这样的： file content aabbcc&#60;&#60;&#60;comment part 1 comment part 2&#62;&#62;&#62; ddeeff 现在需要把[[[...]]]这一段替换为“COMMENT”（为了说明的必要，没有用容易和正则相混淆的字符比如//*{}[]等来举例子），那么sed语法应当是： :begin /&#60;&#60;&#60;/,/&#62;&#62;&#62;/ { /&#62;&#62;&#62;/! { $! { N; b begin } } s/&#60;&#60;&#60;.*&#62;&#62;&#62;/COMMENT/; } 上述语句存储在test.sed中，那么执行的方式和结果就是： $ sed -f test.sed test file content aabbccCOMMENT ddeeff 把正则直接写到命令里面也可以，用“;”来分隔命令即可： $ sed -e ":begin; /&#60;&#60;&#60;/,/&#62;&#62;&#62;/ { /&#62;&#62;&#62;/! { $! { N; b begin }; }; s/&#60;&#60;&#60;.*&#62;&#62;&#62;/COMMENT/; };" [...]]]></description>
			<content:encoded><![CDATA[<p>sed是*nix下方便的行编辑工具，经常用来替换文件的内容，sed一般都是处理单行的，但通过它的一些内建功能，也能实现跨行替换（即要替换的内容有多行内容）。</p>

<p>解决方法主要来自网上搜到的<a href="http://www.mail-archive.com/debian-chinese-gb@lists.debian.org/msg14118.html">一篇文章</a>，但文中的大侠并没有解释得特别清楚，我对照着其他两个更晦涩的例子（<a href="http://www.panix.com/~elflord/unix/sed.html">一</a>、<a href="http://bbs.chinaunix.net/viewthread.php?tid=279427">二</a>），结合man搞懂了之后，记录于此。</p>

<p>假设我们的目标文件test内容是这样的：</p>

<pre><code>file content
  aabbcc&lt;&lt;&lt;comment part 1
  comment part 2&gt;&gt;&gt;
  ddeeff
</code></pre>

<p>现在需要把[[[...]]]这一段替换为“COMMENT”（为了说明的必要，没有用容易和正则相混淆的字符比如//*{}[]等来举例子），那么sed语法应当是：</p>

<pre><code>:begin
/&lt;&lt;&lt;/,/&gt;&gt;&gt;/ {
    /&gt;&gt;&gt;/! {
        $! {
            N;
             b begin
        }
    }
    s/&lt;&lt;&lt;.*&gt;&gt;&gt;/COMMENT/;
}
</code></pre>

<p>上述语句存储在test.sed中，那么执行的方式和结果就是：</p>

<pre><code>$ sed -f test.sed test
        file content
          aabbccCOMMENT
          ddeeff
</code></pre>

<p>把正则直接写到命令里面也可以，用“;”来分隔命令即可：</p>

<pre><code>$ sed -e ":begin; /&lt;&lt;&lt;/,/&gt;&gt;&gt;/ { /&gt;&gt;&gt;/! { $! { N; b begin }; }; s/&lt;&lt;&lt;.*&gt;&gt;&gt;/COMMENT/; };" test
        file content
          aabbccCOMMENT
          ddeeff
</code></pre>

<p>注意右花括号之后也要加上分号“;”，如果再加上<code>-i</code>参数就可以直接把改动写到原文件中去了。</p>

<p>怎么样？看懂了么？我来详细说明吧，看那个多行命令的test.sed文件的内容：</p>

<ul>
<li><p>首先花括号{}代表命令块的开始，类似c的语法，后面就不再说了。</p></li>
<li><p><code>:begin</code>，这是一个标号，man中叫做label，也就是跳转标记，供b和t命令用，本例中使用了b命令。</p></li>
<li><p><code>/&lt;&lt;&lt;/,/&gt;&gt;&gt;/</code>，这是一个地址范围（Addresses），后面{}中的命令只对地址范围之间的内容使用。其中逗号前面的部分是开始地址，逗号后面是结束地址，都是正则表达式。由于sed是“流”式“行”处理，所以结束地址是可以省略的，即如果地址的结束范围不存在，那么将一直处理到文件结尾。本例中使用这个地址范围主要是缩小处理的数据量，因为虽然后面用N命令把对一行的处理扩展为了多行，但如果从文件开头一直N扩展到&lt;&lt;&lt;出现为止，buffer中要处理的字符串可能会很长，影响效率。所以去掉这个处理范围也是能够得到正确结果的，比如：</p>

<pre><code>$ sed -e ":begin; { /&gt;&gt;&gt;/! { $! { N; b begin }; }; s/&lt;&lt;&lt;.*&gt;&gt;&gt;/COMMENT/; };" test
or
$ sed -e "{:begin;  /&gt;&gt;&gt;/! { $! { N; b begin }; }; s/&lt;&lt;&lt;.*&gt;&gt;&gt;/COMMENT/; };" test
</code></pre></li>
<li><p><code>/&gt;&gt;&gt;/!</code>，<code>&gt;&gt;&gt;</code>是要替换内容的结束标记，带上<code>!</code>就是说当一行处理完毕之后，如果没有发现结束标记。。。</p></li>
<li><p><code>$!</code>，<code>$</code>在正则中表示字符串结尾，在sed中代表文件的最后一行，本句和上一句结合起来的意思就是：如果在本行没有发现结束标记，并且当前扫描过的行并不是文件的最后一行。</p></li>
<li><p><code>N;</code>，把下一行的内容追加（append）到缓冲区（pattern）之后，在我们的例子中，在处理<code>aabbcc&lt;&lt;&lt;comment part 1</code>这一行的内容时，就会执行到这里，然后把下一行的内容<code>comment part 2&gt;&gt;&gt;</code>一起放入缓冲区，相当于“合并”成了一行（sed的缓冲区中默认都只会包含一行的内容）。</p></li>
<li><p><code>b begin</code>，由于仍然没有找到结束标记<code>&lt;&lt;&lt;</code>（注意上一条说的缓冲区还没有被处理），所以在这里跳回到标号begin，重新开始命令。如果开始和结束标记之间间隔了多行，那么就会有多次跳转发生。</p></li>
<li><p><code>s/&lt;&lt;&lt;.*&gt;&gt;&gt;/COMMENT/;</code>，终于，<code>/&gt;&gt;&gt;/!</code>不再匹配成功，也就是我们已经找到了结束标记，那么用s命令来进行替换。如果开始和结束标记在一行的话，就会越过上面那些复杂的处理，直接执行到这里了。</p></li>
</ul>

<p>介绍完毕，收工。</p>

<h4>Update @ 2007-12-14</h4>

<p>在和bxy讨论的过程中，又发现sed的另外一种用途，从html或xml中按照tag对应关系，筛选打印出指定的tag内容，使用了正则中的p命令，好像默认就没有“不能处理多行内容”以及“贪婪性”的问题，很好用，很强大：</p>

<pre><code>    $ sed -n -e '/&lt;title&gt;/p' -e '/&lt;text /,/&lt;\/text&gt;/p' from.xml
</code></pre>

<p>注意/<text /和/<\/text>/不在同一行的时候才好用，不然会匹配到下一个实例出现的位置作为结束边界。</text></p>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/regex" title="regex" rel="tag">regex</a>, <a href="http://www.fwolf.com/blog/post/tag/sed" title="sed" rel="tag">sed</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/347" title="升级MT dv 3.0主机到php5 (2007-08-09)">升级MT dv 3.0主机到php5</a> (9)</li>
	<li><a href="http://www.fwolf.com/blog/post/312" title="CSS裸奔节之强制脱衣 (2007-04-05)">CSS裸奔节之强制脱衣</a> (3)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/346/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>CSS裸奔节之强制脱衣</title>
		<link>http://www.fwolf.com/blog/post/312</link>
		<comments>http://www.fwolf.com/blog/post/312#comments</comments>
		<pubDate>Thu, 05 Apr 2007 08:51:02 +0000</pubDate>
		<dc:creator>Fwolf</dc:creator>
				<category><![CDATA[Web Frontend]]></category>
		<category><![CDATA[bookmarklet]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[sed]]></category>

		<guid isPermaLink="false">http://www.fwolf.com/blog/post/312</guid>
		<description><![CDATA[今天是CSS裸奔节，所谓CSS裸奔，就是把网站的所有css去掉，这样所有的显示格式什么的就都没有了，只剩下html实体显示出来，起源好像是比较无聊的想法，就是剥去css的外衣，让大家看看你的(x)html代码是否工整。 不过今天偶不打算裸奔，而是告诉大家一个可以看到任何网站裸奔形象的方法，参考我以前写的用js丰富你的书签功能，创建一个书签，也可以放到书签工具栏上，内容如下： javascript:void((function(){var style=document.getElementsByTagName('style');for (i=0; i&#60;style.length; i++)style.item(i).disabled=true;var link = document.getElementsByTagName('link');for (i=0; i&#60;link.length; i++)if ('text/css' == link.item(i).type)link.item(i).disabled=true;var obj = document.getElementsByTagName('*');for (i=0; i&#60;obj.length; i++){obj1 = obj.item(i);if (obj1.attributes.getNamedItem('style')){obj1.attributes.getNamedItem('style').value = '';}}})()); 注意一定要是一行才行，作为书签地址就可以了，然后打开任何一个网站，点这个书签，是不是把css全部都脱掉了？懒人也可以直接把这个链接拖到工具栏上使用：]]></description>
			<content:encoded><![CDATA[<p>今天是CSS裸奔节，所谓CSS裸奔，就是把网站的所有css去掉，这样所有的显示格式什么的就都没有了，只剩下html实体显示出来，起源好像是比较无聊的想法，就是剥去css的外衣，让大家看看你的(x)html代码是否工整。</p>

<p>不过今天偶不打算裸奔，而是告诉大家一个<strong>可以看到任何网站裸奔形象的方法</strong>，参考我以前写的用<a href="203">js丰富你的书签功能</a>，创建一个书签，也可以放到书签工具栏上，内容如下：</p>

<pre><code>javascript:void((function(){var style=document.getElementsByTagName('style');for (i=0; i&lt;style.length; i++)style.item(i).disabled=true;var link = document.getElementsByTagName('link');for (i=0; i&lt;link.length; i++)if ('text/css' == link.item(i).type)link.item(i).disabled=true;var obj = document.getElementsByTagName('*');for (i=0; i&lt;obj.length; i++){obj1 = obj.item(i);if (obj1.attributes.getNamedItem('style')){obj1.attributes.getNamedItem('style').value = '';}}})());
</code></pre>

<p>注意一定要是一行才行，作为书签地址就可以了，然后打开任何一个网站，点这个书签，是不是把css全部都脱掉了？懒人也可以直接把这个链接拖到工具栏上使用：</p>

<p><a href="javascript:void((function(){var style=document.getElementsByTagName('style');for (i=0; i&lt;style.length; i++)style.item(i).disabled=true;var link = document.getElementsByTagName('link');for (i=0; i<link.length; i++)if ('text/css' == link.item(i).type)link.item(i).disabled=true;var obj = document.getElementsByTagName('*');for (i=0; i<obj.length; i++){obj1 = obj.item(i);if (obj1.attributes.getNamedItem('style')){obj1.attributes.getNamedItem('style').value = '';}}})());">CSS裸奔</a></p>

<p>公布源代码如下，没有太复杂的地方，有了DOM说明，知道各个对象的方法和属性之后，把<code>style</code>和<code>link</code>全部禁用，然后把inline的<code>style=""</code>的value全部设置为空串就可以了：</p>

<pre><code>javascript:void((function(){
/* 用style方式引用的css */
var style=document.getElementsByTagName('style');
var s='Style:' + style.length;
for (i=0; i&lt;style.length; i++)
{
    /*s += style.item(i) + '|';*/
    style.item(i).disabled=true;
}
/* 用link方式引用的css */
var link = document.getElementsByTagName('link');
s += 'Link:' + link.length;
for (i=0; i&lt;link.length; i++)
    if ('text/css' == link.item(i).type)
        {
            /*s += link.item(i).href + "|\\n";*/
            link.item(i).disabled=true;
        }
/* 任意对象的style="" */
var obj = document.getElementsByTagName('body').item(0).childNodes;
var obj = document.getElementsByTagName('*');
s += 'Obj:' + obj.length;
for (i=0; i&lt;obj.length; i++)
{   
    obj1 = obj.item(i);
    if (obj1.attributes.getNamedItem('style'))
    {
        s += obj1.nodeName + obj1.attributes.getNamedItem('style').value + "\\n";
        obj1.attributes.getNamedItem('style').value = "";
    }
}
/*alert(s);*/
})());
</code></pre>

<p>这个文件删除掉注释以后，可以用下面这个命令转换为一行：</p>

<pre><code>cat css1.js |tr -d \\\\n |sed -r -e 's/$/\\n/' -e 's/\\t//g'
</code></pre>

<p>这样就得到了上面那段源代码。</p>

<p>javascript程序调试比较麻烦，以前我的方法是在vim中编辑，然后用命令转化为一行，再手工粘贴到书签的地址中，执行，然后有错误再回到编辑。不过今天发现一个好方法，其实也就是脑子转个弯儿的事，创建一个html文件，在里面把javascript代码调试好，然后再转换为可以用在书签中的形式。</p>

<p>另外Firefox2的Error Console虽然能够监测js错误，但是如果不小心点了上面的“Messages”，就会发现错误不显示了，需要再点“All”查看所有信息，今天为这是纳闷了半天，因为切换显示错误分类的时候没有任何征兆。</p>

<p>参考：</p>

<ul>
<li><a href="http://naked.dustindiaz.com/">CSS裸奔发起人的网站</a></li>
<li><a href="http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/">Document Object Model (DOM) Level 1 Specification</a></li>
<li><a href="http://www.w3.org/TR/DOM-Level-2-HTML/">Document Object Model (DOM) Level 2 HTML Specification</a></li>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/216">JavaScript Debugger(Venkman)</a></li>
</ul>

	Tags: <a href="http://www.fwolf.com/blog/post/tag/bookmarklet" title="bookmarklet" rel="tag">bookmarklet</a>, <a href="http://www.fwolf.com/blog/post/tag/dom" title="DOM" rel="tag">DOM</a>, <a href="http://www.fwolf.com/blog/post/tag/js" title="js" rel="tag">js</a>, <a href="http://www.fwolf.com/blog/post/tag/sed" title="sed" rel="tag">sed</a><br />

	<h4>Related posts</h4>
	<ul class="st-related-posts">
	<li><a href="http://www.fwolf.com/blog/post/252" title="自己写js代替手工点击 (2006-11-06)">自己写js代替手工点击</a> (0)</li>
	<li><a href="http://www.fwolf.com/blog/post/346" title="用sed替换跨行内容 (2007-08-08)">用sed替换跨行内容</a> (6)</li>
	<li><a href="http://www.fwolf.com/blog/post/203" title="用js丰富你的书签功能 (2006-07-23)">用js丰富你的书签功能</a> (2)</li>
	<li><a href="http://www.fwolf.com/blog/post/401" title="新的广告交换、51.la统计和web标准 (2008-05-06)">新的广告交换、51.la统计和web标准</a> (6)</li>
	<li><a href="http://www.fwolf.com/blog/post/347" title="升级MT dv 3.0主机到php5 (2007-08-09)">升级MT dv 3.0主机到php5</a> (9)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.fwolf.com/blog/post/312/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
