Posts Tagged ‘linux’

Clean temporary files left by editors

Tuesday, June 29th, 2010

打开文件进行编辑或其他操作后,有时会留下一些临时文件。按理只有非正常中止会留下临时文件,但有时即使正常退出仍在硬盘上留下一堆垃圾,可能某些编辑器有 bug。

不过,清理临时文件也不费力,找准文件名特征可以一次性删除它们。

find /var/www -name ".goutputstream-*" -exec rm -rf {} \;

据说 .goutputstream-* 是 GNOME 拷贝粘帖文件时的临时文件。

find /var/www -name ".tmp*~" -exec rm -rf {} \;

.tmp*~ 是 Text Editor 编辑时的临时文件。

保持良好的习惯,不要用 root 身份去执行此类操作,执行前也要再三检查查找起始位置是否正确。

A tool to synchronise Magento database between servers

Monday, June 28th, 2010

我时不时需要在测试服务器上加载生产服务器的实时数据,以前都是把数据下载到本地的测试服务器后,手工键入一些命令完成数据加载,每次都要花费几分钟时间。为了避免一再“浪费”这几分钟,我今天一次性投入了几小时完成了一个 php 脚本。虽然这是为 magento 的数据迁移而写的脚本,但我写完一看,用在其他地方也是可以的。

为了安全起见,该脚本是用 php 命令行运行的,所有输出针对 terminal 美化,不是 browser。保存源码为 data_mover.php,同一目录下要有 mysqldump 得到的经 gzip 的 sql 文件,文件名以 FILENAME_PREFIX 开头,以 .sql.gz 结尾。启动时只需键入

/path/to/php -f data_mover.php

即可。

初始化 PDO 对象时,按理只需要 host=localhost,不需要 unix_socket=MYSQL_SOCKET。但奇怪的是,如果通过 apache 调用本程序(虽然不是本程序的初衷,但我希望它在浏览器下也能运行),仅指定 host=localhost 作 PDO __construct() 参数,会产生一个莫名其妙的错误:

SQLSTATE[HY000] [2002] Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)

似乎是 PDO bug。可以通过 host=127.0.0.1 或者追加 unix_socket=MYSQL_SOCKET 来避免。如果通过 php 命令行启动则没有这个问题。

而后,还涉及怎么删除所有数据表的问题。看似简单的一个问题,我发现 mysql 竟然没有一个类似于 DROP/TRUNCATE TABLE * 单行命令。于是除了本脚本用的方法外,我还想了不下两种办法:

其一,删掉整个数据库重新创建。
mysqladmin -f -h localhost -u (DB_ROOT_USERNAME) -p(DB_ROOT_PASSWORD) drop (DB_NAME)
mysqladmin -h localhost -u (DB_ROOT_USERNAME) -p(DB_ROOT_PASSWORD) create (DB_NAME)
但这需要比数据表操作更高权限的用户,在这个无关大局的脚本里去使用高权限的用户的密码,实在非我所愿。

其二,是我 google 来的,方法很巧,但很可惜,因为 foreign keys 的存在,运行这条命令会出错。
mysqldump -u (DB_USERNAME) -p(DB_PASSWORD) –add-drop-table –no-data (DB_NAME) | grep ^DROP | mysql -u (DB_USERNAME) -p(DB_PASSWORD) (DB_NAME)


<?php

define('MYSQL_SOCKET', '/path/to/mysql/socket');
define('DB_NAME', 'db_name');
define('DB_USERNAME', 'db_username');
define('DB_PASSWORD', 'db_password');
define('FILENAME_PREFIX', 'filename_prefix');
define('TEST_URL', 'http://test.domain/');

if ($handle = opendir(dirname(__FILE__))) {
$found = false;
/* This is the correct way to loop over the directory. */
while (false !== ($file = readdir($handle))) {
if (substr($file, 0, 12) == FILENAME_PREFIX && substr($file, -7) == '.sql.gz') {
if ($found) {
//compare which one is newer
if (filemtime($file) > filemtime($fileFound)) {
$fileFound = $file;
}
}
else {
$found = true;
$fileFound = $file;
}
}
}

if ($found) {
echo "Found the newest file $fileFound, and will work on it.\n";
try {
$pdo = new PDO(
'mysql:host=localhost;dbname=' . DB_NAME . ';unix_socket=' . MYSQL_SOCKET,
DB_USERNAME,
DB_PASSWORD,
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
);
echo "Connected to database.\n";
}
catch (Exception $e) {
die ("Error occurred when connecting to database. Quoting error message: " . $e->getMessage() . "\n");
}
$sql = 'SET FOREIGN_KEY_CHECKS = 0';
$pdo->prepare($sql)->execute();

/* query all tables */
$sql = "SHOW TABLES FROM ". DB_NAME;
$stmt = $pdo->prepare($sql);
$stmt->execute();
$result = $stmtDale->fetchAll(PDO::FETCH_COLUMN, 0);
$magentoTableNames = array();
/* add table name to array */
foreach ($result as $tableName) {
if (substr($tableName, 0, 8) == 'magento_') {
$magentoTableNames[] = $tableName;
}
}

//drop all magento tables
$count = count($magentoTableNames);
if ($count > 0) {
$sql = 'DROP TABLE '. implode(',', $magentoTableNames);
$pdo->prepare($sql)->execute();
echo "Found and dropped $count magento tables.\n";
}
else {
echo "No existing magento tables found.\n";
}

//import data via pipe
echo "Importing data. It may take a while...\n";
$output = shell_exec("gunzip < $fileFound | mysql -h localhost -u " . DB_USERNAME . " -p" . DB_PASSWORD . " " . DB_NAME);
echo "Importing data completed.\n";
if ($output) {
echo "This is output during data import:\n$output\n";
}

//after import, change some data for test domains
$sql = 'UPDATE magento_core_config_data SET value=? WHERE scope=? AND scope_id=? AND path=?';
$stmt = $pdo->prepare($sql);
$stmt->execute(array(TEST_URL, 'default', 0, 'web/unsecure/base_url'));
$stmt->execute(array(TEST_URL, 'default', 0, 'web/secure/base_url'));
$stmt->execute(array(TEST_URL, 'websites', 2, 'web/unsecure/base_url'));
$stmt->execute(array(TEST_URL, 'websites', 2, 'web/secure/base_url'));
echo "Config data changed to fit testing environment.\n";
echo "All missions completed.\n";
}
else {
echo "File not found. What else can I do?\n";
}
closedir($handle);
}
else {
echo "File access not permitted.\n";
}

How can Magento generate sitemap.xml belongs to root?

Tuesday, June 22nd, 2010

今天看到 magento 目录下的 sitemap.xml 的属主和属组分别是 root:root,属性是644,而这一台的 webserver 是以 apache:apache 身份运行的,所以我觉得很奇怪:

  • apache 怎么能建立一个 root:root 的文件?
  • 如果这个文件不是 apache 建的,apache 怎么有权去更新它(最近更新就在今天)?

想了好一会明白过来,sitemap.xml 是 cron job 建的,crontab 这么写

*/10 * * * * /usr/bin/php -f /path/to/magento/cron.php

那么 sitemap.xml 归 root:root 所有就不奇怪了。

我想这样写会好些:

*/10 * * * * sudo -u apache -g apache /usr/bin/php -f /path/to/magento/cron.php

2010年6月29日更新:上行命令不对,设想在 cron job 里以 apache 身份运行 cron.php,但出错。正确的写法应该是:

*/10 * * * * su -c '/usr/bin/php -f /path/to/magento/cron.php' -s /bin/bash apache

Nautilus mount

Tuesday, September 1st, 2009

Nautilus is quite good, easy to use in regards to its mount feature. It can automatically “mount” Windows Share via smb:// protocol. However, some software, e.g. FileZilla (now 3.2.4.1) can not read from or write to smb:// protocol. A genuine Linux mount is more helpful than Nautilus mount.

What Windows can but Linux can not

Friday, July 3rd, 2009

总的来说,Linux 比 Windows 更适合于我。买了新机子,第一天就把 Vista 换成了 Fedora,要是有更多的 OEM 机型预装 Linux 或 No OS (e.g. Extra Value from ebuyer.com) 可供选择就好了。

但迄今发现有两件事 Windows 能做到但 LInux 做不到。

一是 UPnP 客户端。UPnP 好像是微软推出的?虽然它要借助支持 UPnP 的路由器才能实现,虽然大部分路由系统用的是 Linux,但 UPnP 客户端只能在 Windows 下实现。

二是误删除文件的恢复。我指被 deleted 但没有进 Trash 也未被 shredded 的文件。在 Windows 的文件系统下可以事后补救(用第三方的工具恢复),在 ext 文件系统下得事先安装工具才能恢复误删的文件。

或许我会发现更多的 Windows 能而 Linux 不能的任务,或许下个 Fedora 发行版能实现更多的不能。

Linux talks to Linux using Windows languages

Friday, June 5th, 2009

MyBook World Edition 基于 Linux,却是面向 Windows 用户的产品。Linux 用户怎么访问它?我一时犯傻了。

因为我早就破解了我的 MyBook World 的根密码,所以我首先想着用 root 身份、sftp 方式去访问 MyBook World。但是 Windows 用户上载到 MyBook World 的文件所有者是 www-data, root 上载上去的文件 www-data 不可写。我无从得知 www-data 的初始密码,否则我就用 www-data 身份、sftp 方式去访问 MyBook World。如果我强行修改 www-data 初始密码,万一把 MyBook World 搞瘫痪了,一个 network drive 只能当 external drive 用就不值了。

好长时间以后才想到,Fedora 自带 Connect to server -> Windows share 就可以 samba client 去访问 MyBook World。Samba 本来就是为 Windows 和 Linux 之间的通讯开发的,但现在两台 Linux 的机器,因为要照顾到其他 Windows 用户,所以只能用 Samba 来对话。

不管怎么说,问题解决了。只留下一个小小的问题—— Windows 下,\\ip address or netbios name 就可以看到所有的共享文件夹,在 Fedora 的 Connect to server -> Windows share 则必须把共享文件夹作为 share 的名字输入后才能连接,如果只输入 ip address or netbios name 则出现 Cannot display location “smb://ip address or netbios name/” ,no application is registered as handling this file. 那怎么查看所有共享文件夹?

Goodbye, Windows

Tuesday, June 2nd, 2009

在个人桌面应用领域,我也早就想跟 Windows 说 byebye,但一直懒于重装系统。

最近换了台 64位的服务器,虽然硬件指标跟原来的比较,除了 32位升级到64位,其他方面并未有太多提升,但性能却强劲不少。既然服务器的性能能有这么大的提升,为什么不把我的桌面也提升一下?一直埋没了64位的 CPU 两年多,突然很想见识一下它在 64位操作系统下的表现。

于是下载了 Fedora x86_64,擦除了厂商的出厂分区,一键恢复 Windows 也没了,彻底投入 Linux 怀抱。

Config CentOS to use the latest software

Saturday, May 23rd, 2009

1and1 VPS OS 可选清单里没有 Fedora,不得不说是个遗憾。当然 CentOS 也不错,可是以前都没接触,使用 CentOS 会有很长的学习过程,但没办法,只能装个 CentOS 用用看。

以前我调查过,CentOS 讲究兼容性,Fedora 追求技术领先。CentOS 安装真得比当初装 Fedora 要容易(Fedora 从6开始到10,我没有一次是一次启动就安装成功的),今天装CentOS 5很顺利(CentOS 兼容性真的那么好?还是我从 Fedora 学来的经验丰富了?)

装完 CentOS,我就面临一个问题:不能 yum install nginx;yum install php 得来的版本也只是 5.1.6。这个简单的比较才觉得 Fedora 的好。我无法想象我还要下载编译 nginx(那一套我还不熟,怕搞砸了)。不过,Extra Packages for Enterprise Linux (EPEL) 已经做好了一个 repository,只要添加这个 repository,

sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5Server/x86_64/epel-release-5-3.noarch.rpm

然后就可以用 yum install nginx。

但是,yum install php 得来的版本只能是 5.1.6,目前还没找到好办法。

Create a password file for Nginx basic authentication

Saturday, May 16th, 2009

It is really a hard time for me to find a way to create a password file for Nginx basic authentication, because I did not realise htpasswd crpty is not available on Windows.

Nginx documentation only mentions Use crypt(3) encryption for passwords, so I tried so hard with htpasswd.exe but could not generate a file recognised by Nginx. Hours later I found Apache documentation mentions -d is

the default on all platforms but Windows, Netware and TPF. Though possibly supported by htpasswd on all platforms, it is not supported by the httpd server on Windows, Netware and TPF.

I have two things to blame -

  1. I still use Windows to do my everyday work. If my first choice was htpasswd on Linux even without furthur instructions, it would have save me a lot of time.
  2. Nginx documentionation. If Nginx documentation is as good as Apache’s, Nginx may overwhelm the world.

Windows support hard link and symbolic link as well

Monday, February 23rd, 2009

很多地方在解释 Linux 软连接时都喜欢把它比作 Windows 的快捷方式(当然它们是有实质区别的),而且在解释硬连接时找不到 Windows 下的对应事物。

但,我绝没有想到 Windows XP 也能建立如同 Linux 下的硬连接(真正意义上的硬连接,最简单的办法就是下载 Link Shell Extension 来用),据说 Vista 还能建软连接。是不是我的思维太激进了,总认为 Windows 要成为末日黄花?我看到在 Linux 下很普通的技术在 Windows 里也有就觉得很惊奇。