怎样快速删除一个包含成千上万个文件/文件夹的文件夹?

首先声明,我是一只老菜鸟,绝非高手大虾,我能做的事情菜鸟都能做!

linux系统的权限控制很严,想不提权关机是不可能的,但要是提权就不得不输入密码,如果我们自己编写的程序想在23:55关机,难道要我们半夜爬起来输密码?

目前可行的办法就是让能关机的程序替我们关机,咱们到了点就向有关机权力的程序发送信息,让他给关机,这样我们就不用关心关机的具体工作了。

那么这个程序是什么呢?我也不知道,但我知道的是,这个程序使用的DBUS,我们可以通过DBUS向他发送信息,然后关机,就这么简单。
通过截图我们能看到,Dbus里确实有能关机的方法供我们调用,我用的是Ubuntu9.04,我想以后的版本应该都行。
附件:

Screenshot-D-Feet D-Bus debugger.png [ 152.17 KiB | 被浏览 993 次 ]


好了,废话少说,来看看关键代码

代码:
  #include <dbus/dbus-glib.h>
  #include <stdio.h>
  #include <stdlib.h>


  DBusGConnection *bus;
  DBusGProxy *remote_object;
  GError *error = NULL;
  guint i,err,call_ret,ret;

  g_type_init ();

  {
    GLogLevelFlags fatal_mask;
    fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
    fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
    g_log_set_always_fatal (fatal_mask);
  }

  bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
  if (!bus)
    return -1;

  remote_object = dbus_g_proxy_new_for_name (bus,
                                 "org.freedesktop.PowerManagement",
                                 "/org/freedesktop/PowerManagement",
                                 "org.freedesktop.PowerManagement");

  ret=(int)dbus_g_proxy_call (remote_object, "Shutdown", &error,G_TYPE_INVALID);



这就是关机的关键代码,使用了dbus-glib,不用提权,普通用户就能关机。
完整的测试程序在附件
使用方法
./configure
make

然后直接执行./shutdown,按照提示来测试就好,测试前保存好你的文件防止丢失。

下面来讨论下怎么生成makefile,写给像我一样没接触过makefile的人。

在示例中的src目录下的sysctrl目录里就是写好的函数,按照头文件的提示调用就行,如果你想用,直接把sysctrl复制到你的工程里就行。
不过由于代码使用了dbus-glib,给新手重新生成makefile带来了很大的困难,我为了生成一个可用的makefile,费尽周折,百度、goole无数次,不过这期间得到了wenjianhn、oneleaf、cnkilior、tenzu、tsinghan等人的大力支持及顶贴,最终圆满解决。为了这些帮助,没有理由不发帖分享!

看dbus-glib.h这个名字,我们就不难发现,这个程序要想编译,就必须设置好dbus和glib两个库,这就是本程序最大的难点,网上介绍automake的文章不少,可这些文章有一个共同的缺陷,他们处理的对象全是hello world,这个程序除了标准的stdio.h,什么都不依赖,根本不用设置依赖库,我开始的时候,对着网上的教程来,总是不能成功,原因就在此。

网上的教程首先会教你进入工作目录,然后分别执行autoscan、aclocal、autoconf、编辑一个Makefile.am并执行automake --add-missing(此处省略大段文字,可以到网上去看看教程,不想搜索的话,直接看参考资料[1])。要是按照网上的教程来,生成的makefile肯定不能用,因为他没有添加依赖库的相关选项和路径。至于怎么添加这些信息,你可以先按照网上的教程,一步一步做,当碰到我下面提到的情况时,你就停下来,把我的步骤加上,这样这些依赖信息就加上了。

1、执行完autoscan,把configure.scan改名为configure.in后,打开这个文件,在教程修改的基础上,继续修改,在AC_PROG_CC后面加入如下代码

代码:
# Dbus detection
PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.1, have_dbus=yes, have_dbus=no)

if test x$have_dbus = xno ; then
    AC_MSG_ERROR([DBus development libraries not found])
fi
AM_CONDITIONAL(HAVE_DBUS, test x$have_dbus = xyes)

AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)


# Glib detection
PKG_CHECK_MODULES(DBUS_GLIB, gobject-2.0 >= 2.6, have_glib=yes, have_glib=no)

if test x$have_glib = xno ; then
    AC_MSG_ERROR([GLib development libraries not found])
fi

AM_CONDITIONAL(HAVE_GLIB, test x$have_glib = xyes)

AC_SUBST(DBUS_GLIB_CFLAGS)
AC_SUBST(DBUS_GLIB_LIBS)



上面的代码,用于检测和添加Dbus和glib。

2、执行完autoconf后,网上的教程会让你新建一个Makefile.am并编辑,在按照网上的教程做完后,再在这个文件的AUTOMAKE_OPTIONS=foreign后面添加如下代码:

代码:
INCLUDES = \
        $(DBUS_CFLAGS)                          \
        $(DBUS_GLIB_CFLAGS)                     \
        -DDBUS_COMPILATION

LIBS = \
        $(DBUS_LIBS)                            \
        $(DBUS_GLIB_LIBS)                       \
        -ldbus-glib-1


上面的代码主要用于指定include路径及链接路径。

然后把你要编译的文件都加进去,例如我的shutdown_SOURCES=src/main.c src/sysctrl/sysctrl.h src/sysctrl/sysctrl.c 这里面要把文件的相对路径写清楚

好了,网上的教程添加了这两步,就能生成可用的makefile了!
如果你还想用其他的库,又不知道这些依赖关系怎么加进makefile,可以下载个官方的示例工程,看看他们的configure.in(或configure.ac)及Makefile.am是怎么写的,照着葫芦画个瓢加进去。

参考资料
[1]、http://lib.360doc.com/07/0117/16/15540_334685.shtml
[2]、http://www.ibm.com/developerworks/cn/linux/l-makefile/
[3]、http://blog.csdn.net/fmddlmyy/archive/2009/01/16/3798048.aspx

时间仓储,不是很条例,大家凑活着看吧

附件:
sysctrl.tar.bz2 [66.69 KiB]
被下载 23 次

作者: lovekid   发布时间: 2009-12-14

时间仓储

作者: wzssyqa   发布时间: 2009-12-14

代码:
cp /sbin/shutdown /usr/bin/myshut
addgroup shutdown
chown root:shutdown /usr/bin/myshut
chmod 4750 /usr/bin/myshut
usermod -a -G shutdown user_name


然后user_name也可以关机了,用myshut命令即可,跟root使用shutdown一样

这是古老的做法,现在一般用sudo给指定用户或者用户组,添加以root权限执行某条命令的能力

作者: xhy   发布时间: 2009-12-14

mark掉,慢慢看

作者: delectate   发布时间: 2009-12-14

xhy 写道:
代码:
cp /sbin/shutdown /usr/bin/myshut
addgroup shutdown
chown root:shutdown /usr/bin/myshut
chmod 4750 /usr/bin/myshut
usermod -a -G shutdown user_name


然后user_name也可以关机了,用myshut命令即可,跟root使用shutdown一样

这是古老的做法,现在一般用sudo给指定用户或者用户组,添加以root权限执行某条命令的能力

无须pwd?

作者: delectate   发布时间: 2009-12-14

delectate 写道:
xhy 写道:
代码:
cp /sbin/shutdown /usr/bin/myshut
addgroup shutdown
chown root:shutdown /usr/bin/myshut
chmod 4750 /usr/bin/myshut
usermod -a -G shutdown user_name


然后user_name也可以关机了,用myshut命令即可,跟root使用shutdown一样

这是古老的做法,现在一般用sudo给指定用户或者用户组,添加以root权限执行某条命令的能力

无须pwd?


无需

作者: xhy   发布时间: 2009-12-14

xhy 写道:
代码:
cp /sbin/shutdown /usr/bin/myshut
addgroup shutdown
chown root:shutdown /usr/bin/myshut
chmod 4750 /usr/bin/myshut
usermod -a -G shutdown user_name


然后user_name也可以关机了,用myshut命令即可,跟root使用shutdown一样

这是古老的做法,现在一般用sudo给指定用户或者用户组,添加以root权限执行某条命令的能力


哈哈,网上最初查到的就是使用这样的方法,我当时想做一个程序,能想飞鸽传书一样拿这到处去,所以依赖要尽可能少,也不能动不动就设置命令,想到dbus和glib可能每个ubuntu发行版都用(要是Kubuntu就没办法了……),就用了最老土的办法,实在是想不到还有没有其他好办法

作者: lovekid   发布时间: 2009-12-14

lovekid 写道:
xhy 写道:
代码:
cp /sbin/shutdown /usr/bin/myshut
addgroup shutdown
chown root:shutdown /usr/bin/myshut
chmod 4750 /usr/bin/myshut
usermod -a -G shutdown user_name


然后user_name也可以关机了,用myshut命令即可,跟root使用shutdown一样

这是古老的做法,现在一般用sudo给指定用户或者用户组,添加以root权限执行某条命令的能力


哈哈,网上最初查到的就是使用这样的方法,我当时想做一个程序,能想飞鸽传书一样拿这到处去,所以依赖要尽可能少,也不能动不动就设置命令,想到dbus和glib可能每个ubuntu发行版都用(要是Kubuntu就没办法了……),就用了最老土的办法,实在是想不到还有没有其他好办法


很多小软件都是ubuntu only或者redhat only了
生产环境里,大部分是没有glib的,甚至连sudo都没有
而且很多是FreeBSD主机,所以要做的通用并不容易

作者: xhy   发布时间: 2009-12-14

我的打算gnome only了,桌面用户用的,关机代码主要用来实现完成后关机这类功能

作者: lovekid   发布时间: 2009-12-14

是不是说可以不提权就关别人机器了?

作者: Lavande   发布时间: 2009-12-14

Lavande 写道:
是不是说可以不提权就关别人机器了?



没那功能,只能关自己的机,代码又不在别人的机器上,除非你把程序偷偷弄到别人机器上,还得让他运行,提权倒是不用

作者: lovekid   发布时间: 2009-12-14

那个应该是gdm的api吧
gdm在只有一个用户登录时,可以不输sudo密码关机

作者: Bill Lee   发布时间: 2010-01-02

dbus 有没有 shell 的接口,好像 dcop 那样 ...

作者: BigSnake.NET   发布时间: 2010-01-02

代码:
dbus-send --dest="org.freedesktop.PowerManagement" --type="method_call" "/org/freedesktop/PowerManagement" "org.freedesktop.PowerManagement.Shutdown"


?

作者: BigSnake.NET   发布时间: 2010-01-02

BigSnake.NET 写道:
代码:
dbus-send --dest="org.freedesktop.PowerManagement" --type="method_call" "/org/freedesktop/PowerManagement" "org.freedesktop.PowerManagement.Shutdown"


?

正解,直接用 dbus-send 或 qdbus 发送命令到 dbus 总线,一行 shell 搞定。

作者: xiooli   发布时间: 2010-01-02