请教:交互式超时自动关机脚本(已解决)

sh/bash/dash/ksh/zsh等Shell脚本
halfwolf
帖子: 40
注册时间: 2012-01-28 21:27

请教:交互式超时自动关机脚本(已解决)

#1

帖子 halfwolf » 2012-01-28 21:44

我想完成一个脚本,有如下特点
1、 询问用户是否关机,若“Y”则关机,若“N”则不关机,并退出程序;若其他则循环提问;
2、 如果用户无应答则,等待1分钟后再次询问;如果循环30次(即30分钟内)无应答则自动关机,即实现超时关机功能;
3、 该脚本可以被makefile调用;

:em02
新手上路,请各位大牛指导,谢谢!
上次由 halfwolf 在 2012-01-31 20:57,总共编辑 1 次。
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: 请教:交互式超时自动关机脚本

#2

帖子 枫叶饭团 » 2012-01-28 21:48

1,2可以用sleep+循环

3、 该脚本可以被makefile调用;
这个什么意思?
halfwolf
帖子: 40
注册时间: 2012-01-28 21:27

Re: 请教:交互式超时自动关机脚本

#3

帖子 halfwolf » 2012-01-28 22:02

谢谢2楼的兄弟!
其实问题1简单,但问题2就没那么容易了,譬如用read命令与用户交互,则键盘无输入时循环则停止在该行,无法向下进行,不知如何破局?
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: 请教:交互式超时自动关机脚本

#4

帖子 枫叶饭团 » 2012-01-28 22:09

sleep+break怎么样,等待一段时间后自动跳出
delectate
帖子: 18311
注册时间: 2008-01-09 22:41

Re: 请教:交互式超时自动关机脚本

#5

帖子 delectate » 2012-01-28 22:13

“如果用户无应答则,等待1分钟后再次询问”

类似问题曾经难道一批win的码农。最后两个方案诞生了:线程,或者进程守护。

还有不入流的,例如全局变量+vb timer,或者win 的api。

linux,不会。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 请教:交互式超时自动关机脚本

#6

帖子 eexpress » 2012-01-28 22:23

第一个才复杂些呢。输入要回车,那不好玩的。不用模块做不到。
你不如调用zenity吧,只是这没超时退出。或者notify-send,这有超时退出,只是你要研究怎么加按键。

或者用Term::Screen,getch是必须的,你不能等待,否则怎么定时,那要定时中断的。要不,你直接gtk。

你什么脚本,先说。
● 鸣学
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: 请教:交互式超时自动关机脚本

#7

帖子 枫叶饭团 » 2012-01-28 22:25

开启子shell同时运行,算叫线程吧...我算是唯一的办法了,感觉
delectate
帖子: 18311
注册时间: 2008-01-09 22:41

Re: 请教:交互式超时自动关机脚本

#8

帖子 delectate » 2012-01-28 22:27

直接用c吧。scanf神马的。

可是普通c又没有权限关机,g3是root权限,也不能用 /sbin/shutdown

记得有个方法可以g2实现非root关机,论坛有。搜。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 请教:交互式超时自动关机脚本

#9

帖子 eexpress » 2012-01-28 22:59

scanf也是带回车的。getch吧。

普通程序,认证到Xauth,可以获取root的。
● 鸣学
halfwolf
帖子: 40
注册时间: 2012-01-28 21:27

Re: 请教:交互式超时自动关机脚本

#10

帖子 halfwolf » 2012-01-28 23:00

谢谢ee大神,我打算用bash shell,当然perl也可以接受;

谢谢delectate、枫叶饭团兄弟,线程、进程守候应该是个正确的方向;

回车和shutdown都不是困扰,"y"回车,"n"回车已经敲习惯了;
shutdown用ee提供的方法echo $password |sudo -S shutdown -h now;

我明天试一下用主进程负责和用户进行交互,子进程负责计时(timer、即看门狗程序)的方法,子进程丢至后台,如果主程序交互完成后杀死计时进程,如果计时进程先结束则咬死主进程;如果试验成功,我就把程序贴至后续跟贴中;

BTY,
有一个问题困扰我很久,如果交互性脚本在makefile中调用,则无法进行正常交互;譬如,脚本中有read line,我输入"y"后,该字符是乎被传递给make而不是脚本中的read line,不知道我的理解是否正确,谢谢!
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 请教:交互式超时自动关机脚本

#11

帖子 tusooa » 2012-01-28 23:10

代码: 全选

read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
timeout问题怎么会那么复杂额。
read -t 10 var

代码: 全选

] ls -ld //
halfwolf
帖子: 40
注册时间: 2012-01-28 21:27

Re: 请教:交互式超时自动关机脚本

#12

帖子 halfwolf » 2012-01-28 23:16

谢谢11楼,你提供的方法更为简洁;如果该脚本被makefile调用,则无法把键盘输入读入var变量,这个问题有没有办法来解?谢谢!
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 请教:交互式超时自动关机脚本

#13

帖子 tusooa » 2012-01-28 23:38

halfwolf 写了:谢谢11楼,你提供的方法更为简洁;如果该脚本被makefile调用,则无法把键盘输入读入var变量,这个问题有没有办法来解?谢谢!
吾这里测试是可以的。
[bash]tlcr: 0 2012-01-28 23:32 tusooa-laptop /tmp/test
● make
./readvar
ls
var is ls
tlcr: 0 2012-01-28 23:32 tusooa-laptop /tmp/test
● dog readvar
#!/bin/bash

read var
echo var is $var
tlcr: 0 2012-01-28 23:33 tusooa-laptop /tmp/test
● dog Makefile
all :
./readvar
tlcr: 0 2012-01-28 23:33 tusooa-laptop /tmp/test

[/bash]

代码: 全选

] ls -ld //
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 请教:交互式超时自动关机脚本

#14

帖子 lilydjwg » 2012-01-29 21:26

delectate 写了:直接用c吧。scanf神马的。

可是普通c又没有权限关机,g3是root权限,也不能用 /sbin/shutdown

记得有个方法可以g2实现非root关机,论坛有。搜。
用 C 还担心权限不够?dbus 不行的话直接 chown root 然后 chmod u+s!
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 请教:交互式超时自动关机脚本

#15

帖子 lilydjwg » 2012-01-29 21:29

eexpress 写了:scanf也是带回车的。getch吧。

普通程序,认证到Xauth,可以获取root的。
getch 是 DOS 的。Linux 需要对终端进行设置。这里有我写的一个相当于 Windows 的 pause 命令的程序:
[c]
//=====================================================================
// pause
//=====================================================================
#include<stdio.h>
#include<termios.h>
#include<unistd.h>
//---------------------------------------------------------------------
int main(){
char ch;
int fd = 0;
struct termios tm_old, tm;
char* cursorhide = "\033[?25l";
char* cursorshow = "\033[?25h";

printf("%s", cursorhide);
printf("请按任意键继续...");
/* fflush(stdout); */
if(tcgetattr(fd, &tm) < 0)
return -1;
tm_old = tm;
cfmakeraw(&tm);
if(tcsetattr(fd, TCSANOW, &tm) < 0)
return -1;
ch = fgetc(stdin);
if(tcsetattr(fd, TCSANOW, &tm_old) < 0)
return -1;
putchar('\n');
printf("%s", cursorshow);
return 0;
}
//=====================================================================
[/c]
回复