最近在项目中使用了jQuery的BlockUI觉得还不错哦,推荐给广大奋斗在第一线的兄弟们:
如果在项目中你想要点击一个按钮使得页面背景变色然后你事先写好的div什么的显示就可以用以下语句
记得在使用这个插件的时候注意要引入两个js文件
如果你想获得更多的关于BlockUI的知识就去他的官方看一下吧,里面有好多例子大家可以照猫画虎。
如果在项目中你想要点击一个按钮使得页面背景变色然后你事先写好的div什么的显示就可以用以下语句
function showCategoryForm(){
$.blockUI({message:$('#whyForm')});(whyForm是div的id)
$('.blockOverlay').click($.unblockUI);
}
下面的语句是页面恢复: $.blockUI({message:$('#whyForm')});(whyForm是div的id)
$('.blockOverlay').click($.unblockUI);
}
function unblock(){
$.unblockUI();
}
$.unblockUI();
}
记得在使用这个插件的时候注意要引入两个js文件
<script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery.blockUI.js"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.3.2.min.js"></script>
如果你想获得更多的关于BlockUI的知识就去他的官方看一下吧,里面有好多例子大家可以照猫画虎。
sudoers—一个关于哪些用户可以执行哪些命令的列表
描述
sudoers配置文件由两种内容组成:别名(基本变量)和用户说明(user specification)(定义了谁能运行什么).sudoers的语法将在下面用扩展的巴科斯-诺尔范式(Extended Backus-Naur Form,EBNF)描述.如果您不知道什么是EBNF是什么的话也请不要放弃,事实上它很简单,并且下面用它作的定义都是经过注释的.
EBNF的快速指导
EBNF是用来描述某种语言的语法的一种简洁且精确的方法.每一个EBNF定义都是由”production rules”这种形式组成的.例如:
symbol ::= definition | alternate1 |alternate2 ………..
每一个”production rule”都和其它的”production rule”有关联,这样就构成了这种语言的语法.EBNF也包含了下面的操作符,许多读者都能够认出这是正则表达式(regular expression)的符号.但是,不要把它们和通配符(wildcard0搞混淆了.它们有着不同的含义.
? 意味着前面的一个记号(symbol)或者一组记号(group of symbol)是可选的,也就是说,可以出现一次或根本就不出现
* 在前面的一个或者一组记号出现零次或多次
+ 在前面的一个或者一组记号出现一次或多次
括号可以用来把记号组合在一起(to group symbols together),单引号可以把一个字符串按照他的字面意思来解释(这与记号的名字相反).
别名
有四种别名:User_Alias,Runas_Alias,Host_Alias和Cmnd_Alias.
Alias ::= User_Alias User_Alias (: User_Alias)* |
Runas_Alias Runas_Alias (: Runas_Alias)* |
Host_Alias Host_Alias (: Host_Alias)* |
Cmnd_Alias Cmnd_Alias (: Cmnd_Alias)*
User_Alias ::= >Runas_Alias ::= >Host_Alias ::= >Cmnd_Alias ::= >NAME ::= [A-Z]([A-Z][0-9]_)*
每一个别名都是按这种形式定义的:
Alias_Type item2, ………………..
这里Alias_Type是User_Alias,Runas_Alias,Host_Alias,Cmnd_Alias中的一个,NAMEW是一个由大写字母,数字和下划线组成的字符串,并且它必需以一个大写字母开头.可以把同一类型的多个别名定义放在同一行里,中间以一个冒号隔开.例如:
Alias_Type item2, item3 : item5
一个组成合法别名成员的定义紧随其后.(The definitions of what constitutes a valid alias member follow.)
User_List ::= User |
User , User_List
User ::= !* username |
!* %group |
!* +netgroup |
!* User_Alias
(译注:这里应该是
User_List ::= User |
User , User_List
User ::= !* username |
!* #uids |
!* %group |
!* +netgroup |
!* User_Alias
才对)
一个User_List是由一个或多个用户名,用户ID(要加上”#”前缀),系统用户组(要加上”%”前缀),网络组(要加上”+”前缀)或者其它 User_Alias组成.每一个列表项都可以加上一个或多个”!”前缀.奇数个”!”使这个列表项取反,偶数个”!”没有任何作用.(译注:这里的”! “也就是取反啦)
Runas_List ::= Runas_User |
Runas_User , Runas_List
Runas_User ::= !* username |
!* #uid |
!* %group |
!* +netgroup |
!* Runas_Alias
Runas_List和User_List是很相象的,仅仅是用Runas_Aliases替代了User_Aliases
Host_List ::= Host |
Host , Host_List
Host ::= !* hostname |
!* ip_addr |
!* network(/netmask)? |
!* +netgroup |
!* Host_Alias
Host_List 是由一个或者多个主机名,IP地址,网络号,网络组(要加上”+”前缀)或者其他的Host_Alias组成的.同样的,一个列表项的值也可以用”!”来取消.如果您使用了一个网络号但是没有随之指定子网掩码,那么主机的以太网接口的子网掩码将被使用—–如果它能够相配的话.子网掩码可以用点分十进制表示法来指定(如:255.255.255.0),也可以用CIDR(无类型域间选路)表示法指定(采用掩码中1的为数,如:24.这和前面的 255.255.255.0是等价的).主机名可以包含shell风格的通配符(请查看下面的”通配符”一节),但是除非您机器上的hostname命令能返回完整的主机名,为了使通配符有效您需要使用fqdn选项(见下面的”标志”小节)
Cmnd_List ::= Cmnd |
Cmnd , Cmnd_List
commandname ::= filename |
filename args |
filename “”
Cmnd ::= !* commandname |
!* directory |
!* Cmnd_Alias
Cmnd_List 是由一个或多个命令名,目录或者其他Cmnd_Alias组成的列表.命令名是一个可以包含shell风格通配符(请查看下面的”通配符”一节)的完整文件名.一个简单的文件名永许用户以任何他们想使用的参数来执行命令.但是您也可以指定命令行参数(可以包含通配符).您还可以通过交替的使用” “来说明这个命令执行时不能带任何命令行参数.当您在Cmnd_List中指定了一个目录时,用户将可以执行这个目录中的任何文件(不包括子目录中的文件).
如果Cmnd关联上了命令行参数,那么用户在命令行上所给的参数必需精确的匹配Cmnd中的参数(或者要和通配符匹配).注意,如果下面的字符在命令参数中出现的话,必须使用”\”来将其转义: ,, :, =, .
默认项
通过一个或多个Default_Entry行,一些特定的配置选项在运行时可以从它们的默认值改变.(译注:好拗口哦:p)这些选项可以对在任何主机上的所有用户或者在某个特定主机上的所有用户或者仅仅是一个特定的用户产生作用.如果多个条目都匹配,那么它们会按顺序执行.如果有冲突的值,那么最后一个匹配行上的值将会产生作用.
Default_Type ::= Defaults ||
Defaults : User ||
Defaults @ Host
Default_Entry ::= Default_Type Parameter_List
Parameter ::= Parameter = Value ||
Parameter += Value ||
Parameter -= Value ||
!* Parameter ||
Parameters 可以是标志(flags),整数值(integer values),字符串(strings)或者列表(lists).标志是一个布尔值,可以通过使用”!”操作符来取反.一些整数,字符串和列表参数也可以在布尔上下文中使用以使其取反.由多个单词组成的值必须用双引号引起来.一些特殊字符必须用”\”转义.
列表还有两个附加的操作符,+=和-=.这两个操作符被分别用来从一个列表中增加或删除条目.用”-=”操作符从列表中删除不存在的项目并不算是错误.
注意,由于sudoers文件是按顺序解析的,所以放置Default段的最佳位置是在Host,User和Cmnd别名段之后,用户定义段之前.
标志
long_otp_prompt
When validating with a One Time Password scheme (S/Key or OPIE), a two-line prompt is used to make it easier to cut and paste the challenge to a local window. Its not as pretty as the default but some people find it more convenient. This flag is off by default.
(译注:这一段我还没读懂,贴原文上来吧)
ignore_dot
如果设置(为on)的话,sudo将会忽略PATH环境变量中的.或者(就是当前目录).PATH本身不会被修改.这个标志默认是on.
mail_always
每当有用户使用sudo时就给mailto user发送一封邮件.此标志默认是off.
mail_badpass
当用户使用sudo但是却输入了错误的口令时将给mailto user发送一封邮件.此标志默认是off.
mail_no_user
如果使用sudo的用户在sudoers中没有记录的话将给mailto user发送一封邮件.此标志默认为on.
mail_no_host
如果使用sudo的用户在sudoers中有记录,但是他不被永许在正在使用的主机上使用sudo,将给mailto user(请查看”可以用在布尔上下文中的字符串”一节)发送一封邮件.此标志默认为off.
mail_no_perms
如果用户有使用sudo的权限,但是他试图用sudo使用的命令在sudoers中没有列出来,那么给mailto user发送一封邮件.此标志默认为off.
tty_tickets
如果设置(为on)的话,用户必须使用基于终端(tty)的的验证方法.一般的,sudo在ticket dir里使用一个与执行sudo的用户同名的目录.这个标志设置后,sudo将在那个目录中使用一个与执行sudo的用户登录tty同名的文件.此标志默认为on.
lecture
如果设置(为on)的话,初次使用sudo的用户将收到一个简短的lecture.此标志默认为on.
authenticate
如果设置(为on)的话,用户在用sudo执行命令之前必须通过口令(或者通过其他的方式)来验证身分.这个默认选项可以通过设置PASSWD和NOPASSWD标签(tags)来覆盖.此标志默认为on.
root_sudo
如果设置(为on)的话,root也将被永许使用sudo.将此标志设置为off来阻值用户通过使用类似于”sudo sudo /bin/sh”这样的连锁sudo命令来获得一个root权限的shell.此标志默认为on.
log_host
如果设置(为on)的话,主机名将被记录在sudo的日志文件(不是系统日志)中.此标志默认为off.
log_year
如果设置(为on)的话,四位的年份将被记录在sudo的日志文件(不是系统日志)中).此标志默认为off.
shell_noargs
如果设置(为on)并且sudo并未带任何参数执行的话,sudo的表现就象是带-s选项一样.也就是说,将会以root身分运行一个shell(如果 SHELL环境变量被设置的话,这个shell就是SHELL定义的shell,否则,将运行用户/etc/passwd中项的shell字段定义的 shell).此标志默认为off.
set_home
如果设置(为on)并且sudo是带-s选项执行的话,HOME环境变量将被设置为目标用户(target user)(除非sudo使用了-u选项,目标用户就是root)的主目录.这实际上使-s选项包含了-H选项.此标志默认为off.
always_set_home
如果设置(为on)的话,sudo将把HOME环境变量设置为目标用户(target user)(除非sudo使用了-u选项,目标用户就是root)的主目录.这实际上意味着-H选项总是被包含.此标志默认是off.
path_info
一般来说,如果一个命令不能在PATH环境变量中找到的话,sudo将会告诉用户.但是某些站点可能会希望禁止这个特性.因为这可以用来收集一些关于普通用户没有权限执行的命令的位置的信息.不利之处在于,如果命令只是不在用户的PATH中的话,sudo将告诉用户他们不被永许执行这些命令,这可能会把人高糊涂.此标志默认是off.
preserve_groups
默认地,sudo会初始化目标用户(target user)所在组列表的组向量(译注:原文是By default sudo will initialize the group vector to the list of groups the target user is in.)preserve_groups设置后,用户已存在的组向量将被保存不变.真实组ID和有效组ID仍然会被设置与目标用户相匹配.此标志默认是 off,
fqdn
如果您想在sudoers中使用完整主机名的话,请设置此项.例如:使用myhost.mydomain.edu来替代 myhost.设置后如果原意的话您也可以使用短格式(甚至把两种格式混合起来使用).注意,打开fqdn标志需要让sudo进行DNS解析,而如果 DNS停止工作(例如机器没有连入网络)的话会导致sudo无法使用.同时需要注意的是,您必须使用DNS知道的主机正式名称,也就是说您不能使用主机的别名(CNAME entry),因为您无法从DNS处得到所有的别名.如果您机器的主机名(就是hostname命令的输出)已经是完整格式,您就不需要设置fqdn.此标志默认是off.
insults
如果设置(为on)的话,sudo将会侮辱(insult)输入错误口令的用户(译注:这也可以?:p).此标志默认为off.
requiretty
如果设置(为on)的话,sudo仅仅在用户从一个真正的tty上登录时才会执行.这将不永许像”rsh somehost sudo ls”这样的命令,因为rsh并不分配一个tty.因为当没有tty存在时无法关闭echo,所以一些站点可能会希望设置这个标志来阻止用户输入可见(回显)的口令.此标志默认为off.
env_editor
如果设置(为on)的话,visudo将使用在EDITOR或者VISUAL环境变量中定义的编辑器,如果EDITOR和VISUAL都没有定义的话将使用默认的编辑器列表.注意,这可能造成一个安全漏洞,因为这永许用户以root身份运行任意的命令而不被日志记录.一个安全的变通方法是在editor(见下面的”字符串”小节)中保存一个用冒号分隔的编辑器列表.这样visudo将仅仅使用EDITOR或者VISUAL中定义的编辑器—–如果它们和editor列表中的某个项目匹配的话.
rootpw
如果设置(为on)的话,sudo将提示输入root的口令而不是执行sudo命令的用户的口令.此标志默认为off.
runaspw
如果设置(为on)的话,sudo将提示输入由runsa_default选项定义的用户(默认为root)的口令而不是执行sudo命令的用户的口令.此标志默认为off.
targetpw
如果设置(为on)的话,sudo将提示输入由sudo的-u选项指定的用户(默认为root)的口令而不是执行sudo的用户的口令.此标志默认为off.
set_logname
一般地,sudo将把LOGNAME和USER环境变量设置为目标用户(除非使用了-u选项的话,就是root)的名字.但是,因为一些程序(包括RCS版本控制系统)使用LOGNAME来确认用户的真实身份,它可能想要改变这种行为,这可以通过取消set_logname选项来实现.
stay_setuid
一般地,当sudo执行一个命令时,真实UID和有效UID都被设置为目标用户(默认是root)的UID.这个选项改变了这种行为,它把真实UID保留为执行sudo的用户的UID.换句话说,这使sudo成为了一个setuid程序.这在那些当setuid程序运行时禁用一些有潜在危险的功能的系统上会很有用.尽管如此,请注意这意味着sudo运行时的真实UID将是执行sudo命令的用户的UID,这可能会允许用户在能够在日志中记录下一个 failure之前杀死sudo,这倚赖于您的操作系统如何定义信号和setuid进程之间的相互作用.
env_reset
如果设置(为 on)的话,sudo将把环境重置为只包含下列变量:HOME,LOGNAME,PATH,SHELL,TERM和USER(此外还有SUDO_*).在这些变量中,只有TERM保留原环境中的值不变,其他的变量都被设置为默认值(值可能被set_logname选项修改).如果sudo编译时加入了 SECURE_PATH选项,它的值将被作为PATH环境变量的值.其他的变量可以由设置env_keep选项来保存.
use_loginclass
设置(为on)的话,sudo将执行对目标用户的登录类指定的默认动作—-如果存在的话.此选项仅仅在sudo配置时带有–with-logincap选项时才存在.此标志默认是off.
整数
passwd_tries
sudo向日志中写入一个failure并退出之前允许用户输入口令的次数,默认为3.
可以用在布尔上下文中的整数(integers that can be used in a boolean context)
loglinelen
日志文件每行中的字母数.这个值用来决定日志文件中什么时候折行.这个选项仅影响sudo的日志,而对系统日志文件没有影响.默认值为80(使用0或者取消此选项来禁止折行).
timestamp_timeout
sudo再次询问口令之前逝去的时间(以分钟记).默认值为5.如果想要总是询问口令的话请把此值设置为0.如果设置为负数的话,用户的时间戳永远不会过期.这可以用来允许用户分别使用sudo -v和sudo -k来建立或者删除他们自己的时间戳.
passwd_timeout
sudo的口令询问超时时间(分钟记).默认为5.设置为0可以取消口令超时.
umask
执行命令时使用的umask值.要保留用户的umask值的话请取消此选项或者设置为0777.此选项的默认值为0022.
字符串
mailsub
发送给mailto user的邮件使用的主题.转义字符%h将被扩展为机器的主机名.默认值为”*** SECURITY information for %h ***”.
badpass_message
当用户输入了错误的口令时显示的信息.除非设置了insults的话,默认值将为”Sorry, try again.”
timestampdir
sudo存储时间戳文件的目录.默认值为/var/run/sudo
passprompt
询问口令时的提示.可以被sudo的-p选项或者SUDO_PROMPT环境变量所覆盖.这里提供了两个转义字符:%u将被扩展为用户的登录名,而%h将被扩展为本地主机名.此选项的默认值为”Password:”.
runas_default
使用sudo但没有指定-u标志时使用的默认用户.默认为root
syslog_goodpri
用户身份验证成功时使用的系统日志优先级.默认为notice
syslog_badpri
用户身份验证成功时使用的系统日志优先级.默认为alert
editor
用冒号分隔开的一个允许visudo使用的编辑器列表.可能的话visudo将选择使用和用户的USER环境变量相匹配的那个编辑器,或者是列表中的第一个存在且可执行的编辑器.默认值为您系统中vi编辑器的路径.
可以用在布尔上下文中的字符串(strings that can used in a boolean context)
logfile
sudo日志(不是系统日志)的存放位置.设置一个路径来打开日志功能,取消设置将关闭日志功能.(Seting a path turns on logging to a file; negating this option turns it off.)
syslog
如果起用了syslog的话将使用的系统日志设施(取消此选项来禁用系统日志记录)(译注:原文为:Syslog facility if syslog is being used for logging (negate to disable syslog logging)).默认为arthpriv.
mailerpath
用来发送报警邮件的邮件程序的路径.默认值是sendmail的路径.
mailerflags
使用邮件程序时的标记,默认为 -t.
mailto
发送报警邮件和错误邮件的目的地址.这个地址必须用双引号引起来,以免sudo解释”@”符号.默认值为root.
exempt_group
在此组中的用户将不要求口令和PATH.此选项默认没有设置.
verifypw
此选项控制当用户使用带有-v选项的sudo时,何时要求口令.它可以有下面可能的值:
all:当前主机上sudoers中所有的用户条目都必须设置NOPASSWD标志来避免输入口令.
any:当前主机上sudoers中至少有一个用户条目必须设置NOPASSWD标志来避免输入口令.
never:用户使用-v标志但从不需要输入口令.
always:用户使用-v标志但总是需要输入口令.
默认的值是”all”.
listpw
此选项控制当用户使用带有-l选项的sudo时,何时要求口令.它可以有下面可能的值:
all:[/size当前主机上sudoers中所有的用户条目都必须设置NOPASSWD标志来避免输入口令.
any:当前主机上sudoers中至少有一个用户条目必须设置NOPASSWD标志来避免输入口令.
never:用户使用-l标志但从不需要输入口令.
always:用户使用-l标志但总是需要输入口令.
默认值为"any".
可以在布尔上下文中使用的列表(lists that can be used in a boolean context)
env_check
如果含有"%"或者"/"字符的话将从用户的环境中删除的环境变量.这将预防拙劣的程序中printf风格的格式所带来的伤害.这个参数可以是一个用双引号引起,由空格分隔的列表,或者是一个不带引号的单值.这个列表可以通过分别使用"=",+=","-=","!"来重写,增添,删除或取反.当以root 身份执行带-V选项的sudo命令时会打印出默认需要检察的环境变量列表.
env_delete
将从用户的环境中删除的环境变量.这个参数可以是一个用双引号引起,由空格分隔的列表,或者是一个不带引号的单值.这个列表可以通过分别使用"=",+=","-=","!"来重写,增添,删除或取反.当以root身份执行带-V选项的sudo命令时会打印出默认将被删除的环境变量列表.
env_keep
当env_reset选项生效时将在用户的环境中保留的环境变量.这允许对sudo派生的进程的环境进行精密的控制.这个列表可以通过分别使用"=",+=","-=","!"来重写,增添,删除或取反.此列表默认没有成员.
当使用系统日志进行日志记录时,sudo将接受下列值作为系统日志设施(译注:原文为When logging via syslog(3), sudo accepts the following values for the syslog facility)(syslog参数的值):authpriv(如果您的操作系统支持的话),auth,daemon,user,local0, local1,local2,local3,local4,local5,local6和local7.下列系统日志优先级是被支持的:alert, crit,debug,emerg,err,info,notice和warning.
用户说明(user specification)
User_Spec ::= User_list Host_List = Cmnd_Spec_List \
(: User_Spec)*
Cmnd_Spec_List ::= Cmnd_Spec |
Cmnd_Spec , Cmnd_Spec_List
Cmnd_Spec ::= Runas_Spec? (NOPASSWD: | PASSWD:)? Cmnd
Runas_Spec ::= ( Runas_List )
用户说明决定在一个特定的主机上一个用户能够执行哪些命令.这些命令默认以root身份执行,但可以进行基于每个命令的更改.(译注:原文为By default, commands are run as root,but this can be changed on a per-command basis)
让我们把它分成下面这些部分:
Runas_Spec
Runas_Spec 是一个用括号括起的一个简单的Runas_List(在上面已经定义了),如果您在用户说明中没有指定一个Runas_Spec的话,将会使用默认的 root的Runas_Spec(译注:这里原文为:If you do not specify a Runas_Spec in the user specification, a default Runas_Spec of root will be used).Runas_Spec设置了他后面所跟命令的默认项(译注:原文为A Runas_Spec sets the default for commands that follow it,这句话我实在是不知道怎么翻译,暂且这么译吧).对于下面的条目:
dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/who
(译注:这里应该是dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm)
这意味着用户dgb可以运行/binls,/bin/kill和/usr/bin/lprm---但是只能以operator的身份执行.例如:
sudo -u operator /bin/ls
在一个条目的后面改写Runas_Spec也是可能的.如果我们把上面的条目改成这样:
dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
这样用户dgb执行/bin/ls命令是以operator身份,但执行/bin/kill和/usr/bin/lprm命令就是以root身份.
NOPASSWD和PASSWD
默认地,sudo在用户执行一个命令前会验证用户的身份.通过NOPASSWD标签可以更改这个行为.就象Runas_Spec一样,NOPASSWD标签给跟在它后面的Cmnd_Spec_List中的命令设置了一个默认项(译注:原文是Like a Runas_Spec, the NOPASSWD tag sets a default for the commands that follow it in the Cmnd_Spec_List).PASSWD标签可以做相反的事.例如:
ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
这将会允许用户ray在不进行身份验证的情况下在主机rushmore上以root身份运行/bin/kill,/bin/ls和/usr/bin/lprm命令.如果您想让ray在不提供口令的情况下只是可以运行/bin/kill,那么可以修改上面的条目为:
ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
注意,尽管如此,PASSWD标签对于在exempt_group选项中指定了的组中的用户无效.
默认地,如果对当前主机上的某个用户的任何一个条目设置了NOPASSWD标签的话,他将能够运行sudo -l而不提供口令.另外,如果对属于当前主机的用户的所有条目都设置了NOPASSWD标签的话,这个用户就只能运行sudo -v而不提供口令.(译注:前面两句话的原文是By default, if the NOPASSWD tag is applied to any of the entries for a user on the current host, he or she will be able to run sudo -l without a password. Additionally, a user may only run sudo -v without a password if the NOPASSWD tag is present for all a users entries that pertain to the current host).这个行为可以通过设置verifypw和listpw选项来更改.
通配符(又称meta字符)
sudo允许在sudoers中的路径名和命令行参数中使用shell风格的通配符.通配符匹配是通过POSIX的fnmatch标准程序实现的.注意,这不是正则表达式.
* 匹配任意一组零个或者多个字符
? 匹配任意一个字符
[...] 匹配任意一个在大括号中指定范围里的字符
[!...] 匹配任何一个不在大括号中指定范围里的字符
\x 任意一个字符”x”识别为单纯的”x”.这用来转义像”*”,”?”,”[","]“和”}”这样的一些特殊字符
注意,路径名中的通配符不会匹配正斜线(“/”).在匹配命令行参数时,因为斜线不被通配符匹配,这使/usr/bin/*匹配/usr/bin/who而不匹配/usr/bin/X11/xterm.
通配符规则的例外
对上面的规则有下面的例外:
“”"” 如果空字符串”"是sudoers条目中仅有的命令行参数,这意味着这条命令执行时不允许带有任何参数.
其它的特殊字符和保留字
美元符(“#”)被用来指明一条注释(除非它出现在用户名上下文中并且后面跟有一个或多个数字,在这种情况下它被作为一个UID来对待).所有的注释字符和任何的文本,直到一行的结尾都将被忽略
保留字ALL是ailas中经常导致成功匹配的单位.它可以在任何可以使用Cmnd_Alias,User_Alias, Runas_Alias, 或Host_Alias的地方使用.您不应该试图定义一个名为ALL的别名,因为aleas中的单位将用作您的个人偏好.请注意,在命令上下文 (command context)中使用ALL是非常危险的,它允许用户在系统上运行任何命令.
感叹号(“!”)可以在别名中和Cmnd前用作逻辑非操作符.这允许排除一些特定的值.尽管如此,但请注意,联合ALL别名中的单位使用”!”将允许用户蓄意执行罕见的除了少数以外的所有命令(译注: 原文是Note ,however, that using a ! in conjunction with the built in ALL ailas to allow a user to run “all but few” commands rarely works as intended)(参阅下面的”安全要点”一节).
可以在一行的末尾使用反斜线(“\”)来在下一行延续此行,此时这两行将作为完整的一行对待.
列表元素和用户说明中的特殊语法字符之间的空格是可选的.
下面的字符作为一个词的一部分(例如,一个用户名或者一个主机名)出现时必需使用反斜线(“\”)来转义:”@”,”!”,”=”,”:”, “,”, “(“, “)”, “\”.
示例
下面是sudoers条目的示例.显然,一些示例有点不自然.首先,我们定义别名:
# User alias specification
User_Alias FULLTIMERS = millert, mikef, dowdy
User_Alias PARTTIMERS = bostley, jwfox, crawl
User_Alias WEBMASTERS = will, wendy, wim
# Runas alias specification
Runas_Alias OP = root, operator
Runas_Alias DB = oracle, sybase
# Host alias specification
Host_Alias SPARC = bigtime, eclipse, moet, anchor :\
SGI = grolsch, dandelion, black :\
ALPHA = widget, thalamus, foobar :\
HPPA = boa, nag, python
Host_Alias CUNETS = 128.138.0.0/255.255.0.0
Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
Host_Alias SERVERS = master, mail, www, ns
Host_Alias CDROM = orion, perseus, hercules
# Cmnd alias specification
Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
/usr/sbin/restore, /usr/sbin/rrestore
Cmnd_Alias KILL = /usr/bin/kill
Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
Cmnd_Alias HALT = /usr/sbin/halt, /usr/sbin/fasthalt
Cmnd_Alias REBOOT = /usr/sbin/reboot, /usr/sbin/fastboot
Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
/usr/local/bin/tcsh, /usr/bin/rsh, \
/usr/local/bin/zsh
Cmnd_Alias SU = /usr/bin/su
接下来我们改写了一些编译进的默认值.我们希望sudo在所有情况下使用auth设施在系统日志中作记录.我们不想总是输出初次使用sudo的提示,并且用户millert使用sudo不需要口令.另外,我们为SERVERS Host_Alias中的主机维护一个附加的本地日志文件.并且由于这个日志需要保存许多年,我们要在日志的每一行中加入年份信息.
# Override built in defaults
Defaults syslog=auth
Defaults:FULLTIMERS !lecture
Defaults:millert !authenticate
Defaults@SERVERS log_year, logfile=/var/log/sudo.log
实际上决定谁能运行什么的是用户说明部分:
root ALL = (ALL) ALL
%wheel ALL = (ALL) ALL
我们让root和wheel组的成员可以在任何主机上以任何人的身份运行任何命令.
FULLTIMERS ALL = NOPASSWD: ALL
专职系统管理员(millert,mikef和dowdy)可以在任何主机上执行任何命令而不需要进行身份验证.
PARTTIMERS ALL = ALL
兼职系统管理员(bostley,jwfox和crawl)可以在任何主机上运行任何命令,但他们首先必须进行身份验证(因为这个条目没有NOPASSWD标签).
jack CSNETS = ALL
用户jack可以在CSNETS别名(网络128.138.243.0,128.138.204.0和128.138.242.0)中的机器上运行任何命令.在这些网络中,只有128.138.204.0明确的给出了掩码(用CIDR方式),指明这是个C类网.对CSNETS中的其他网络来说,如果本地主机的掩码匹配的话将使用本地主机的掩码.
lisa CUNETS = ALL
用户lisa可以在CUNETS别名(B类网络128.138.0.0)中的任何主机上执行任何命令.
operator ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\
/usr/oper/bin/
用户operator可以执行的命令被限制在一个简单的maintenance中.这里就是和备份,杀死进程,打印系统,关闭系统和任何在/usr/oper/bin/中的命令.
joe ALL = /usr/bin/su operator
用户joe只能su成operator.
pete HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
用户pete可以修改HPPA上除了root以外任何用户的口令.注意,这里人为passwd不会在命令行上使用多个用户名.
bob SPARC = (OP) ALL : SGI = (OP) ALL
用户可以在SPARC和SGI上以任何在OP Runas_Alias中列出的用户(root和operator)的身份运行任何命令.
jim +biglab = ALL
用户jim可以在biglab网络用户组中的机器上运行任何命令.因为biglab前面加上了前缀”+”,所以sudo知道这是一个网络用户组.
+secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
网络用户组secretaries中的用户需要帮助管理打印机和进行增删用户的工作,所以需要允许他们在任何机器上执行这些命令.
fred ALL = (DB) NOPASSWD: ALL
用户fred可以在DB Runas_Alias (oracle 或 sybase)上以任何人的身份执行任何命令而不需要提供口令.
john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
用户john可以在ALPHA上su成除root的任何人,但是不允许他给su加上任何标志执行.
jen ALL, !SERVERS = ALL
用户jen可以在除了SERVERS Host_Alias (master, mail, www 和 ns)以外的任何机器上执行任何命令.
jill SERVERS = /usr/bin/, !SU, !SHELLS
用户jill可以在任何SERVERS Host_Alias中的机器上运行/usr/bin/下除了属于SU和SHELLS Cmnd_Aliases外的任何命令.
steve CSNETS = (operator) /usr/local/op_commands/
用户steve可以在任何CSNETS中的机器上执行/usr/local/op_commands/中的所有命令,但是只能以operator的身份.
matt valkyrie = KILL
用户matt应该可以在他自己的工作站valkyrie上杀死挂起的进程.
WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
任何在WEBMASTERS User_Alias (will, wendy,和 wim)中的用户都能够在主机www上以www(网页的所有者)的身份执行任何命令,或者简单的su成www.
ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\
/sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
所有的用户都应该能够在 CDROM Host_Alias (orion, perseus, hercules)中的主机上mount和unmount光盘驱动器而不需要输入口令.对用户来说敲入这么长的命令有些冗长而乏味,所以把它封装在一个 shell脚本中是一个最佳的选择.
安全要点
使用”!”来从ALL中减去命令一般来说不会产生预期作用.用户可以简单的通过把希望执行的命令改名执行的法子来绕过限制.例如:
bill ALL = ALL, !SU, !SHELLS
这并不会阻止bill执行SU和SHELLS中列出的命令.他只需要把这些命令改一个名字,或者从一个编辑器或者其他程序中escape到shell(译注:原文是use a shell escape from an editor or other program)就可以运行了.所以这种类型的限制至少应该经过深思熟虑(并从策略上加强它).
CAVEATS
sudoers必需总是使用visudo命令来编辑,因为它会锁定文件并且进行语法检察.这强制sudoers摆脱语法错误,因为sudoers有语法错误时sudo是不会运行的.
当使用机器的网络用户组时(与用户相反),如果您在网络用户组中存贮了完整的主机名(这经常是事实),您需要让主机名像hostname命令的输出一样是完整的或者在sudoers中使用fqdn选项.
文件
/etc/sudoers 谁能作什么的一个列表
/etc/group 本地组文件
/etc/netgroup 网络组文件
描述
sudoers配置文件由两种内容组成:别名(基本变量)和用户说明(user specification)(定义了谁能运行什么).sudoers的语法将在下面用扩展的巴科斯-诺尔范式(Extended Backus-Naur Form,EBNF)描述.如果您不知道什么是EBNF是什么的话也请不要放弃,事实上它很简单,并且下面用它作的定义都是经过注释的.
EBNF的快速指导
EBNF是用来描述某种语言的语法的一种简洁且精确的方法.每一个EBNF定义都是由”production rules”这种形式组成的.例如:
symbol ::= definition | alternate1 |alternate2 ………..
每一个”production rule”都和其它的”production rule”有关联,这样就构成了这种语言的语法.EBNF也包含了下面的操作符,许多读者都能够认出这是正则表达式(regular expression)的符号.但是,不要把它们和通配符(wildcard0搞混淆了.它们有着不同的含义.
? 意味着前面的一个记号(symbol)或者一组记号(group of symbol)是可选的,也就是说,可以出现一次或根本就不出现
* 在前面的一个或者一组记号出现零次或多次
+ 在前面的一个或者一组记号出现一次或多次
括号可以用来把记号组合在一起(to group symbols together),单引号可以把一个字符串按照他的字面意思来解释(这与记号的名字相反).
别名
有四种别名:User_Alias,Runas_Alias,Host_Alias和Cmnd_Alias.
Alias ::= User_Alias User_Alias (: User_Alias)* |
Runas_Alias Runas_Alias (: Runas_Alias)* |
Host_Alias Host_Alias (: Host_Alias)* |
Cmnd_Alias Cmnd_Alias (: Cmnd_Alias)*
User_Alias ::= >Runas_Alias ::= >Host_Alias ::= >Cmnd_Alias ::= >NAME ::= [A-Z]([A-Z][0-9]_)*
每一个别名都是按这种形式定义的:
Alias_Type item2, ………………..
这里Alias_Type是User_Alias,Runas_Alias,Host_Alias,Cmnd_Alias中的一个,NAMEW是一个由大写字母,数字和下划线组成的字符串,并且它必需以一个大写字母开头.可以把同一类型的多个别名定义放在同一行里,中间以一个冒号隔开.例如:
Alias_Type item2, item3 : item5
一个组成合法别名成员的定义紧随其后.(The definitions of what constitutes a valid alias member follow.)
User_List ::= User |
User , User_List
User ::= !* username |
!* %group |
!* +netgroup |
!* User_Alias
(译注:这里应该是
User_List ::= User |
User , User_List
User ::= !* username |
!* #uids |
!* %group |
!* +netgroup |
!* User_Alias
才对)
一个User_List是由一个或多个用户名,用户ID(要加上”#”前缀),系统用户组(要加上”%”前缀),网络组(要加上”+”前缀)或者其它 User_Alias组成.每一个列表项都可以加上一个或多个”!”前缀.奇数个”!”使这个列表项取反,偶数个”!”没有任何作用.(译注:这里的”! “也就是取反啦)
Runas_List ::= Runas_User |
Runas_User , Runas_List
Runas_User ::= !* username |
!* #uid |
!* %group |
!* +netgroup |
!* Runas_Alias
Runas_List和User_List是很相象的,仅仅是用Runas_Aliases替代了User_Aliases
Host_List ::= Host |
Host , Host_List
Host ::= !* hostname |
!* ip_addr |
!* network(/netmask)? |
!* +netgroup |
!* Host_Alias
Host_List 是由一个或者多个主机名,IP地址,网络号,网络组(要加上”+”前缀)或者其他的Host_Alias组成的.同样的,一个列表项的值也可以用”!”来取消.如果您使用了一个网络号但是没有随之指定子网掩码,那么主机的以太网接口的子网掩码将被使用—–如果它能够相配的话.子网掩码可以用点分十进制表示法来指定(如:255.255.255.0),也可以用CIDR(无类型域间选路)表示法指定(采用掩码中1的为数,如:24.这和前面的 255.255.255.0是等价的).主机名可以包含shell风格的通配符(请查看下面的”通配符”一节),但是除非您机器上的hostname命令能返回完整的主机名,为了使通配符有效您需要使用fqdn选项(见下面的”标志”小节)
Cmnd_List ::= Cmnd |
Cmnd , Cmnd_List
commandname ::= filename |
filename args |
filename “”
Cmnd ::= !* commandname |
!* directory |
!* Cmnd_Alias
Cmnd_List 是由一个或多个命令名,目录或者其他Cmnd_Alias组成的列表.命令名是一个可以包含shell风格通配符(请查看下面的”通配符”一节)的完整文件名.一个简单的文件名永许用户以任何他们想使用的参数来执行命令.但是您也可以指定命令行参数(可以包含通配符).您还可以通过交替的使用” “来说明这个命令执行时不能带任何命令行参数.当您在Cmnd_List中指定了一个目录时,用户将可以执行这个目录中的任何文件(不包括子目录中的文件).
如果Cmnd关联上了命令行参数,那么用户在命令行上所给的参数必需精确的匹配Cmnd中的参数(或者要和通配符匹配).注意,如果下面的字符在命令参数中出现的话,必须使用”\”来将其转义: ,, :, =, .
默认项
通过一个或多个Default_Entry行,一些特定的配置选项在运行时可以从它们的默认值改变.(译注:好拗口哦:p)这些选项可以对在任何主机上的所有用户或者在某个特定主机上的所有用户或者仅仅是一个特定的用户产生作用.如果多个条目都匹配,那么它们会按顺序执行.如果有冲突的值,那么最后一个匹配行上的值将会产生作用.
Default_Type ::= Defaults ||
Defaults : User ||
Defaults @ Host
Default_Entry ::= Default_Type Parameter_List
Parameter ::= Parameter = Value ||
Parameter += Value ||
Parameter -= Value ||
!* Parameter ||
Parameters 可以是标志(flags),整数值(integer values),字符串(strings)或者列表(lists).标志是一个布尔值,可以通过使用”!”操作符来取反.一些整数,字符串和列表参数也可以在布尔上下文中使用以使其取反.由多个单词组成的值必须用双引号引起来.一些特殊字符必须用”\”转义.
列表还有两个附加的操作符,+=和-=.这两个操作符被分别用来从一个列表中增加或删除条目.用”-=”操作符从列表中删除不存在的项目并不算是错误.
注意,由于sudoers文件是按顺序解析的,所以放置Default段的最佳位置是在Host,User和Cmnd别名段之后,用户定义段之前.
标志
long_otp_prompt
When validating with a One Time Password scheme (S/Key or OPIE), a two-line prompt is used to make it easier to cut and paste the challenge to a local window. Its not as pretty as the default but some people find it more convenient. This flag is off by default.
(译注:这一段我还没读懂,贴原文上来吧)
ignore_dot
如果设置(为on)的话,sudo将会忽略PATH环境变量中的.或者(就是当前目录).PATH本身不会被修改.这个标志默认是on.
mail_always
每当有用户使用sudo时就给mailto user发送一封邮件.此标志默认是off.
mail_badpass
当用户使用sudo但是却输入了错误的口令时将给mailto user发送一封邮件.此标志默认是off.
mail_no_user
如果使用sudo的用户在sudoers中没有记录的话将给mailto user发送一封邮件.此标志默认为on.
mail_no_host
如果使用sudo的用户在sudoers中有记录,但是他不被永许在正在使用的主机上使用sudo,将给mailto user(请查看”可以用在布尔上下文中的字符串”一节)发送一封邮件.此标志默认为off.
mail_no_perms
如果用户有使用sudo的权限,但是他试图用sudo使用的命令在sudoers中没有列出来,那么给mailto user发送一封邮件.此标志默认为off.
tty_tickets
如果设置(为on)的话,用户必须使用基于终端(tty)的的验证方法.一般的,sudo在ticket dir里使用一个与执行sudo的用户同名的目录.这个标志设置后,sudo将在那个目录中使用一个与执行sudo的用户登录tty同名的文件.此标志默认为on.
lecture
如果设置(为on)的话,初次使用sudo的用户将收到一个简短的lecture.此标志默认为on.
authenticate
如果设置(为on)的话,用户在用sudo执行命令之前必须通过口令(或者通过其他的方式)来验证身分.这个默认选项可以通过设置PASSWD和NOPASSWD标签(tags)来覆盖.此标志默认为on.
root_sudo
如果设置(为on)的话,root也将被永许使用sudo.将此标志设置为off来阻值用户通过使用类似于”sudo sudo /bin/sh”这样的连锁sudo命令来获得一个root权限的shell.此标志默认为on.
log_host
如果设置(为on)的话,主机名将被记录在sudo的日志文件(不是系统日志)中.此标志默认为off.
log_year
如果设置(为on)的话,四位的年份将被记录在sudo的日志文件(不是系统日志)中).此标志默认为off.
shell_noargs
如果设置(为on)并且sudo并未带任何参数执行的话,sudo的表现就象是带-s选项一样.也就是说,将会以root身分运行一个shell(如果 SHELL环境变量被设置的话,这个shell就是SHELL定义的shell,否则,将运行用户/etc/passwd中项的shell字段定义的 shell).此标志默认为off.
set_home
如果设置(为on)并且sudo是带-s选项执行的话,HOME环境变量将被设置为目标用户(target user)(除非sudo使用了-u选项,目标用户就是root)的主目录.这实际上使-s选项包含了-H选项.此标志默认为off.
always_set_home
如果设置(为on)的话,sudo将把HOME环境变量设置为目标用户(target user)(除非sudo使用了-u选项,目标用户就是root)的主目录.这实际上意味着-H选项总是被包含.此标志默认是off.
path_info
一般来说,如果一个命令不能在PATH环境变量中找到的话,sudo将会告诉用户.但是某些站点可能会希望禁止这个特性.因为这可以用来收集一些关于普通用户没有权限执行的命令的位置的信息.不利之处在于,如果命令只是不在用户的PATH中的话,sudo将告诉用户他们不被永许执行这些命令,这可能会把人高糊涂.此标志默认是off.
preserve_groups
默认地,sudo会初始化目标用户(target user)所在组列表的组向量(译注:原文是By default sudo will initialize the group vector to the list of groups the target user is in.)preserve_groups设置后,用户已存在的组向量将被保存不变.真实组ID和有效组ID仍然会被设置与目标用户相匹配.此标志默认是 off,
fqdn
如果您想在sudoers中使用完整主机名的话,请设置此项.例如:使用myhost.mydomain.edu来替代 myhost.设置后如果原意的话您也可以使用短格式(甚至把两种格式混合起来使用).注意,打开fqdn标志需要让sudo进行DNS解析,而如果 DNS停止工作(例如机器没有连入网络)的话会导致sudo无法使用.同时需要注意的是,您必须使用DNS知道的主机正式名称,也就是说您不能使用主机的别名(CNAME entry),因为您无法从DNS处得到所有的别名.如果您机器的主机名(就是hostname命令的输出)已经是完整格式,您就不需要设置fqdn.此标志默认是off.
insults
如果设置(为on)的话,sudo将会侮辱(insult)输入错误口令的用户(译注:这也可以?:p).此标志默认为off.
requiretty
如果设置(为on)的话,sudo仅仅在用户从一个真正的tty上登录时才会执行.这将不永许像”rsh somehost sudo ls”这样的命令,因为rsh并不分配一个tty.因为当没有tty存在时无法关闭echo,所以一些站点可能会希望设置这个标志来阻止用户输入可见(回显)的口令.此标志默认为off.
env_editor
如果设置(为on)的话,visudo将使用在EDITOR或者VISUAL环境变量中定义的编辑器,如果EDITOR和VISUAL都没有定义的话将使用默认的编辑器列表.注意,这可能造成一个安全漏洞,因为这永许用户以root身份运行任意的命令而不被日志记录.一个安全的变通方法是在editor(见下面的”字符串”小节)中保存一个用冒号分隔的编辑器列表.这样visudo将仅仅使用EDITOR或者VISUAL中定义的编辑器—–如果它们和editor列表中的某个项目匹配的话.
rootpw
如果设置(为on)的话,sudo将提示输入root的口令而不是执行sudo命令的用户的口令.此标志默认为off.
runaspw
如果设置(为on)的话,sudo将提示输入由runsa_default选项定义的用户(默认为root)的口令而不是执行sudo命令的用户的口令.此标志默认为off.
targetpw
如果设置(为on)的话,sudo将提示输入由sudo的-u选项指定的用户(默认为root)的口令而不是执行sudo的用户的口令.此标志默认为off.
set_logname
一般地,sudo将把LOGNAME和USER环境变量设置为目标用户(除非使用了-u选项的话,就是root)的名字.但是,因为一些程序(包括RCS版本控制系统)使用LOGNAME来确认用户的真实身份,它可能想要改变这种行为,这可以通过取消set_logname选项来实现.
stay_setuid
一般地,当sudo执行一个命令时,真实UID和有效UID都被设置为目标用户(默认是root)的UID.这个选项改变了这种行为,它把真实UID保留为执行sudo的用户的UID.换句话说,这使sudo成为了一个setuid程序.这在那些当setuid程序运行时禁用一些有潜在危险的功能的系统上会很有用.尽管如此,请注意这意味着sudo运行时的真实UID将是执行sudo命令的用户的UID,这可能会允许用户在能够在日志中记录下一个 failure之前杀死sudo,这倚赖于您的操作系统如何定义信号和setuid进程之间的相互作用.
env_reset
如果设置(为 on)的话,sudo将把环境重置为只包含下列变量:HOME,LOGNAME,PATH,SHELL,TERM和USER(此外还有SUDO_*).在这些变量中,只有TERM保留原环境中的值不变,其他的变量都被设置为默认值(值可能被set_logname选项修改).如果sudo编译时加入了 SECURE_PATH选项,它的值将被作为PATH环境变量的值.其他的变量可以由设置env_keep选项来保存.
use_loginclass
设置(为on)的话,sudo将执行对目标用户的登录类指定的默认动作—-如果存在的话.此选项仅仅在sudo配置时带有–with-logincap选项时才存在.此标志默认是off.
整数
passwd_tries
sudo向日志中写入一个failure并退出之前允许用户输入口令的次数,默认为3.
可以用在布尔上下文中的整数(integers that can be used in a boolean context)
loglinelen
日志文件每行中的字母数.这个值用来决定日志文件中什么时候折行.这个选项仅影响sudo的日志,而对系统日志文件没有影响.默认值为80(使用0或者取消此选项来禁止折行).
timestamp_timeout
sudo再次询问口令之前逝去的时间(以分钟记).默认值为5.如果想要总是询问口令的话请把此值设置为0.如果设置为负数的话,用户的时间戳永远不会过期.这可以用来允许用户分别使用sudo -v和sudo -k来建立或者删除他们自己的时间戳.
passwd_timeout
sudo的口令询问超时时间(分钟记).默认为5.设置为0可以取消口令超时.
umask
执行命令时使用的umask值.要保留用户的umask值的话请取消此选项或者设置为0777.此选项的默认值为0022.
字符串
mailsub
发送给mailto user的邮件使用的主题.转义字符%h将被扩展为机器的主机名.默认值为”*** SECURITY information for %h ***”.
badpass_message
当用户输入了错误的口令时显示的信息.除非设置了insults的话,默认值将为”Sorry, try again.”
timestampdir
sudo存储时间戳文件的目录.默认值为/var/run/sudo
passprompt
询问口令时的提示.可以被sudo的-p选项或者SUDO_PROMPT环境变量所覆盖.这里提供了两个转义字符:%u将被扩展为用户的登录名,而%h将被扩展为本地主机名.此选项的默认值为”Password:”.
runas_default
使用sudo但没有指定-u标志时使用的默认用户.默认为root
syslog_goodpri
用户身份验证成功时使用的系统日志优先级.默认为notice
syslog_badpri
用户身份验证成功时使用的系统日志优先级.默认为alert
editor
用冒号分隔开的一个允许visudo使用的编辑器列表.可能的话visudo将选择使用和用户的USER环境变量相匹配的那个编辑器,或者是列表中的第一个存在且可执行的编辑器.默认值为您系统中vi编辑器的路径.
可以用在布尔上下文中的字符串(strings that can used in a boolean context)
logfile
sudo日志(不是系统日志)的存放位置.设置一个路径来打开日志功能,取消设置将关闭日志功能.(Seting a path turns on logging to a file; negating this option turns it off.)
syslog
如果起用了syslog的话将使用的系统日志设施(取消此选项来禁用系统日志记录)(译注:原文为:Syslog facility if syslog is being used for logging (negate to disable syslog logging)).默认为arthpriv.
mailerpath
用来发送报警邮件的邮件程序的路径.默认值是sendmail的路径.
mailerflags
使用邮件程序时的标记,默认为 -t.
mailto
发送报警邮件和错误邮件的目的地址.这个地址必须用双引号引起来,以免sudo解释”@”符号.默认值为root.
exempt_group
在此组中的用户将不要求口令和PATH.此选项默认没有设置.
verifypw
此选项控制当用户使用带有-v选项的sudo时,何时要求口令.它可以有下面可能的值:
all:当前主机上sudoers中所有的用户条目都必须设置NOPASSWD标志来避免输入口令.
any:当前主机上sudoers中至少有一个用户条目必须设置NOPASSWD标志来避免输入口令.
never:用户使用-v标志但从不需要输入口令.
always:用户使用-v标志但总是需要输入口令.
默认的值是”all”.
listpw
此选项控制当用户使用带有-l选项的sudo时,何时要求口令.它可以有下面可能的值:
all:[/size当前主机上sudoers中所有的用户条目都必须设置NOPASSWD标志来避免输入口令.
any:当前主机上sudoers中至少有一个用户条目必须设置NOPASSWD标志来避免输入口令.
never:用户使用-l标志但从不需要输入口令.
always:用户使用-l标志但总是需要输入口令.
默认值为"any".
可以在布尔上下文中使用的列表(lists that can be used in a boolean context)
env_check
如果含有"%"或者"/"字符的话将从用户的环境中删除的环境变量.这将预防拙劣的程序中printf风格的格式所带来的伤害.这个参数可以是一个用双引号引起,由空格分隔的列表,或者是一个不带引号的单值.这个列表可以通过分别使用"=",+=","-=","!"来重写,增添,删除或取反.当以root 身份执行带-V选项的sudo命令时会打印出默认需要检察的环境变量列表.
env_delete
将从用户的环境中删除的环境变量.这个参数可以是一个用双引号引起,由空格分隔的列表,或者是一个不带引号的单值.这个列表可以通过分别使用"=",+=","-=","!"来重写,增添,删除或取反.当以root身份执行带-V选项的sudo命令时会打印出默认将被删除的环境变量列表.
env_keep
当env_reset选项生效时将在用户的环境中保留的环境变量.这允许对sudo派生的进程的环境进行精密的控制.这个列表可以通过分别使用"=",+=","-=","!"来重写,增添,删除或取反.此列表默认没有成员.
当使用系统日志进行日志记录时,sudo将接受下列值作为系统日志设施(译注:原文为When logging via syslog(3), sudo accepts the following values for the syslog facility)(syslog参数的值):authpriv(如果您的操作系统支持的话),auth,daemon,user,local0, local1,local2,local3,local4,local5,local6和local7.下列系统日志优先级是被支持的:alert, crit,debug,emerg,err,info,notice和warning.
用户说明(user specification)
User_Spec ::= User_list Host_List = Cmnd_Spec_List \
(: User_Spec)*
Cmnd_Spec_List ::= Cmnd_Spec |
Cmnd_Spec , Cmnd_Spec_List
Cmnd_Spec ::= Runas_Spec? (NOPASSWD: | PASSWD:)? Cmnd
Runas_Spec ::= ( Runas_List )
用户说明决定在一个特定的主机上一个用户能够执行哪些命令.这些命令默认以root身份执行,但可以进行基于每个命令的更改.(译注:原文为By default, commands are run as root,but this can be changed on a per-command basis)
让我们把它分成下面这些部分:
Runas_Spec
Runas_Spec 是一个用括号括起的一个简单的Runas_List(在上面已经定义了),如果您在用户说明中没有指定一个Runas_Spec的话,将会使用默认的 root的Runas_Spec(译注:这里原文为:If you do not specify a Runas_Spec in the user specification, a default Runas_Spec of root will be used).Runas_Spec设置了他后面所跟命令的默认项(译注:原文为A Runas_Spec sets the default for commands that follow it,这句话我实在是不知道怎么翻译,暂且这么译吧).对于下面的条目:
dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/who
(译注:这里应该是dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm)
这意味着用户dgb可以运行/binls,/bin/kill和/usr/bin/lprm---但是只能以operator的身份执行.例如:
sudo -u operator /bin/ls
在一个条目的后面改写Runas_Spec也是可能的.如果我们把上面的条目改成这样:
dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
这样用户dgb执行/bin/ls命令是以operator身份,但执行/bin/kill和/usr/bin/lprm命令就是以root身份.
NOPASSWD和PASSWD
默认地,sudo在用户执行一个命令前会验证用户的身份.通过NOPASSWD标签可以更改这个行为.就象Runas_Spec一样,NOPASSWD标签给跟在它后面的Cmnd_Spec_List中的命令设置了一个默认项(译注:原文是Like a Runas_Spec, the NOPASSWD tag sets a default for the commands that follow it in the Cmnd_Spec_List).PASSWD标签可以做相反的事.例如:
ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
这将会允许用户ray在不进行身份验证的情况下在主机rushmore上以root身份运行/bin/kill,/bin/ls和/usr/bin/lprm命令.如果您想让ray在不提供口令的情况下只是可以运行/bin/kill,那么可以修改上面的条目为:
ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
注意,尽管如此,PASSWD标签对于在exempt_group选项中指定了的组中的用户无效.
默认地,如果对当前主机上的某个用户的任何一个条目设置了NOPASSWD标签的话,他将能够运行sudo -l而不提供口令.另外,如果对属于当前主机的用户的所有条目都设置了NOPASSWD标签的话,这个用户就只能运行sudo -v而不提供口令.(译注:前面两句话的原文是By default, if the NOPASSWD tag is applied to any of the entries for a user on the current host, he or she will be able to run sudo -l without a password. Additionally, a user may only run sudo -v without a password if the NOPASSWD tag is present for all a users entries that pertain to the current host).这个行为可以通过设置verifypw和listpw选项来更改.
通配符(又称meta字符)
sudo允许在sudoers中的路径名和命令行参数中使用shell风格的通配符.通配符匹配是通过POSIX的fnmatch标准程序实现的.注意,这不是正则表达式.
* 匹配任意一组零个或者多个字符
? 匹配任意一个字符
[...] 匹配任意一个在大括号中指定范围里的字符
[!...] 匹配任何一个不在大括号中指定范围里的字符
\x 任意一个字符”x”识别为单纯的”x”.这用来转义像”*”,”?”,”[","]“和”}”这样的一些特殊字符
注意,路径名中的通配符不会匹配正斜线(“/”).在匹配命令行参数时,因为斜线不被通配符匹配,这使/usr/bin/*匹配/usr/bin/who而不匹配/usr/bin/X11/xterm.
通配符规则的例外
对上面的规则有下面的例外:
“”"” 如果空字符串”"是sudoers条目中仅有的命令行参数,这意味着这条命令执行时不允许带有任何参数.
其它的特殊字符和保留字
美元符(“#”)被用来指明一条注释(除非它出现在用户名上下文中并且后面跟有一个或多个数字,在这种情况下它被作为一个UID来对待).所有的注释字符和任何的文本,直到一行的结尾都将被忽略
保留字ALL是ailas中经常导致成功匹配的单位.它可以在任何可以使用Cmnd_Alias,User_Alias, Runas_Alias, 或Host_Alias的地方使用.您不应该试图定义一个名为ALL的别名,因为aleas中的单位将用作您的个人偏好.请注意,在命令上下文 (command context)中使用ALL是非常危险的,它允许用户在系统上运行任何命令.
感叹号(“!”)可以在别名中和Cmnd前用作逻辑非操作符.这允许排除一些特定的值.尽管如此,但请注意,联合ALL别名中的单位使用”!”将允许用户蓄意执行罕见的除了少数以外的所有命令(译注: 原文是Note ,however, that using a ! in conjunction with the built in ALL ailas to allow a user to run “all but few” commands rarely works as intended)(参阅下面的”安全要点”一节).
可以在一行的末尾使用反斜线(“\”)来在下一行延续此行,此时这两行将作为完整的一行对待.
列表元素和用户说明中的特殊语法字符之间的空格是可选的.
下面的字符作为一个词的一部分(例如,一个用户名或者一个主机名)出现时必需使用反斜线(“\”)来转义:”@”,”!”,”=”,”:”, “,”, “(“, “)”, “\”.
示例
下面是sudoers条目的示例.显然,一些示例有点不自然.首先,我们定义别名:
# User alias specification
User_Alias FULLTIMERS = millert, mikef, dowdy
User_Alias PARTTIMERS = bostley, jwfox, crawl
User_Alias WEBMASTERS = will, wendy, wim
# Runas alias specification
Runas_Alias OP = root, operator
Runas_Alias DB = oracle, sybase
# Host alias specification
Host_Alias SPARC = bigtime, eclipse, moet, anchor :\
SGI = grolsch, dandelion, black :\
ALPHA = widget, thalamus, foobar :\
HPPA = boa, nag, python
Host_Alias CUNETS = 128.138.0.0/255.255.0.0
Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
Host_Alias SERVERS = master, mail, www, ns
Host_Alias CDROM = orion, perseus, hercules
# Cmnd alias specification
Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
/usr/sbin/restore, /usr/sbin/rrestore
Cmnd_Alias KILL = /usr/bin/kill
Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
Cmnd_Alias HALT = /usr/sbin/halt, /usr/sbin/fasthalt
Cmnd_Alias REBOOT = /usr/sbin/reboot, /usr/sbin/fastboot
Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
/usr/local/bin/tcsh, /usr/bin/rsh, \
/usr/local/bin/zsh
Cmnd_Alias SU = /usr/bin/su
接下来我们改写了一些编译进的默认值.我们希望sudo在所有情况下使用auth设施在系统日志中作记录.我们不想总是输出初次使用sudo的提示,并且用户millert使用sudo不需要口令.另外,我们为SERVERS Host_Alias中的主机维护一个附加的本地日志文件.并且由于这个日志需要保存许多年,我们要在日志的每一行中加入年份信息.
# Override built in defaults
Defaults syslog=auth
Defaults:FULLTIMERS !lecture
Defaults:millert !authenticate
Defaults@SERVERS log_year, logfile=/var/log/sudo.log
实际上决定谁能运行什么的是用户说明部分:
root ALL = (ALL) ALL
%wheel ALL = (ALL) ALL
我们让root和wheel组的成员可以在任何主机上以任何人的身份运行任何命令.
FULLTIMERS ALL = NOPASSWD: ALL
专职系统管理员(millert,mikef和dowdy)可以在任何主机上执行任何命令而不需要进行身份验证.
PARTTIMERS ALL = ALL
兼职系统管理员(bostley,jwfox和crawl)可以在任何主机上运行任何命令,但他们首先必须进行身份验证(因为这个条目没有NOPASSWD标签).
jack CSNETS = ALL
用户jack可以在CSNETS别名(网络128.138.243.0,128.138.204.0和128.138.242.0)中的机器上运行任何命令.在这些网络中,只有128.138.204.0明确的给出了掩码(用CIDR方式),指明这是个C类网.对CSNETS中的其他网络来说,如果本地主机的掩码匹配的话将使用本地主机的掩码.
lisa CUNETS = ALL
用户lisa可以在CUNETS别名(B类网络128.138.0.0)中的任何主机上执行任何命令.
operator ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\
/usr/oper/bin/
用户operator可以执行的命令被限制在一个简单的maintenance中.这里就是和备份,杀死进程,打印系统,关闭系统和任何在/usr/oper/bin/中的命令.
joe ALL = /usr/bin/su operator
用户joe只能su成operator.
pete HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
用户pete可以修改HPPA上除了root以外任何用户的口令.注意,这里人为passwd不会在命令行上使用多个用户名.
bob SPARC = (OP) ALL : SGI = (OP) ALL
用户可以在SPARC和SGI上以任何在OP Runas_Alias中列出的用户(root和operator)的身份运行任何命令.
jim +biglab = ALL
用户jim可以在biglab网络用户组中的机器上运行任何命令.因为biglab前面加上了前缀”+”,所以sudo知道这是一个网络用户组.
+secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
网络用户组secretaries中的用户需要帮助管理打印机和进行增删用户的工作,所以需要允许他们在任何机器上执行这些命令.
fred ALL = (DB) NOPASSWD: ALL
用户fred可以在DB Runas_Alias (oracle 或 sybase)上以任何人的身份执行任何命令而不需要提供口令.
john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
用户john可以在ALPHA上su成除root的任何人,但是不允许他给su加上任何标志执行.
jen ALL, !SERVERS = ALL
用户jen可以在除了SERVERS Host_Alias (master, mail, www 和 ns)以外的任何机器上执行任何命令.
jill SERVERS = /usr/bin/, !SU, !SHELLS
用户jill可以在任何SERVERS Host_Alias中的机器上运行/usr/bin/下除了属于SU和SHELLS Cmnd_Aliases外的任何命令.
steve CSNETS = (operator) /usr/local/op_commands/
用户steve可以在任何CSNETS中的机器上执行/usr/local/op_commands/中的所有命令,但是只能以operator的身份.
matt valkyrie = KILL
用户matt应该可以在他自己的工作站valkyrie上杀死挂起的进程.
WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
任何在WEBMASTERS User_Alias (will, wendy,和 wim)中的用户都能够在主机www上以www(网页的所有者)的身份执行任何命令,或者简单的su成www.
ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\
/sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
所有的用户都应该能够在 CDROM Host_Alias (orion, perseus, hercules)中的主机上mount和unmount光盘驱动器而不需要输入口令.对用户来说敲入这么长的命令有些冗长而乏味,所以把它封装在一个 shell脚本中是一个最佳的选择.
安全要点
使用”!”来从ALL中减去命令一般来说不会产生预期作用.用户可以简单的通过把希望执行的命令改名执行的法子来绕过限制.例如:
bill ALL = ALL, !SU, !SHELLS
这并不会阻止bill执行SU和SHELLS中列出的命令.他只需要把这些命令改一个名字,或者从一个编辑器或者其他程序中escape到shell(译注:原文是use a shell escape from an editor or other program)就可以运行了.所以这种类型的限制至少应该经过深思熟虑(并从策略上加强它).
CAVEATS
sudoers必需总是使用visudo命令来编辑,因为它会锁定文件并且进行语法检察.这强制sudoers摆脱语法错误,因为sudoers有语法错误时sudo是不会运行的.
当使用机器的网络用户组时(与用户相反),如果您在网络用户组中存贮了完整的主机名(这经常是事实),您需要让主机名像hostname命令的输出一样是完整的或者在sudoers中使用fqdn选项.
文件
/etc/sudoers 谁能作什么的一个列表
/etc/group 本地组文件
/etc/netgroup 网络组文件
为何慢:
可以用ssh的详细模式跟踪(ssh -v x.x.x.x)一下,是不是DNS反解析?
这个问题正是最后面那项 GSSAPIAuthentication 引起的,打开这个ssh的时候可能会先去尝试其他的认证方式.很多地方都会介绍说修改 /etc/ssh/ssh_config 文件,但是其实这并不是最好的办法,因为在下次升级的时候,也许会因为配置文件被修改过,而引起不必要的麻烦.我的解决办法是修改个人用户的配置文件,如下:
echo “GSSAPIAuthentication no” >> ~/.ssh/config
1)修改:/etc/ssh/ssh_config 文件:GSSAPIAuthentication no ,UseDNS no。 vi /etc/ssh/sshd_config ,别少了个D。
2)也可以修改:~/.ssh/config :GSSAPIAuthentication no ,echo “GSSAPIAuthentication no” >> ~/.ssh/config
阅读全文
可以用ssh的详细模式跟踪(ssh -v x.x.x.x)一下,是不是DNS反解析?
这个问题正是最后面那项 GSSAPIAuthentication 引起的,打开这个ssh的时候可能会先去尝试其他的认证方式.很多地方都会介绍说修改 /etc/ssh/ssh_config 文件,但是其实这并不是最好的办法,因为在下次升级的时候,也许会因为配置文件被修改过,而引起不必要的麻烦.我的解决办法是修改个人用户的配置文件,如下:
echo “GSSAPIAuthentication no” >> ~/.ssh/config
1)修改:/etc/ssh/ssh_config 文件:GSSAPIAuthentication no ,UseDNS no。 vi /etc/ssh/sshd_config ,别少了个D。
2)也可以修改:~/.ssh/config :GSSAPIAuthentication no ,echo “GSSAPIAuthentication no” >> ~/.ssh/config
阅读全文
#!/bin/bash
#filename:getar
#desp:get a tar file from a dir!
out=`pwd`/admin_output
pike=/usr/bin/pike
if [ -n "$1" -a "$1" != "${1//[^0-9]/}” ];then
echo “The first parameter is not a number!”
exit
elif [[ $1 == "" ]];then
echo “The first parameter is null!”
exit
fiif [ -n "$2" -a "$2" != "${2//[^0-9]/}” ];then
echo “The second parameter is not a number!”
exit
elif [[ $2 == "" ]];then
echo “The second parameter is null!”
exit
else
touch /tmp/pike.tmp
sleep 10
$pike process_kaiqi_cid.pike $1 $2
while true;do
if [[ -e output/cid$2/standard/operamini-hifi_kaiqi-zh.jad && -e output/cid$2/standard/operamini-hifi_kaiqi-zh.jar ]];then
find `pwd`/output -type f -newer /tmp/pike.tmp | xargs tar czf $out/$1-$2.tgz >/dev/null 2>&1
rm -rf /tmp/pike.tmp
echo -e “\033[0;32;1mit’s ok\033[0m”
break
fi
done
fi
在处理一个大数据量数据库的时候
突然发现mysql对于count(*)的不同处理会造成不同的结果
比如执行
SELECT count(*) FROM tablename
即使对于千万级别的数据mysql也能非常迅速的返回结果
而对于
SELECT count(*) FROM tablename WHERE…..
mysql的查询时间开始攀升
仔细查阅累下手册,发现当没有WHERE语句对于整个mysql的表进行count运算的时候
MyISAM类型的表中保存有总的行数,而当添加有WHERE限定语句的时候Mysql需要对整个表进行检索
从而得出count的数值
突然又想起来看到的不少新兴的php程序对于count的处理并没有很好的意识到这点
记录下
顺便提下mysql的DISTINCT的关键字有很多你想不到的用处
1.在count 不重复的记录的时候能用到
比如SELECT COUNT( DISTINCT id ) FROM tablename;
就是计算talbebname表中id不同的记录有多少条
2,在需要返回记录不同的id的具体值的时候可以用
比如SELECT DISTINCT id FROM tablename;
返回talbebname表中不同的id的具体的值
3.上面的情况2对于需要返回mysql表中2列以上的结果时会有歧义
比如SELECT DISTINCT id, type FROM tablename;
实际上返回的是 id与type同时不相同的结果,也就是DISTINCT同时作用了两个字段,必须得id与tyoe都相同的才被排除了,与我们期望的结果不一样
4.这时候可以考虑使用group_concat函数来进行排除,不过这个mysql函数是在mysql4.1以上才支持的
5.其实还有另外一种解决方式,就是使用
SELECT id, type, count(DISTINCT id) FROM tablename
虽然这样的返回结果多了一列无用的count数据(或许你就需要这个我说的无用数据)
返回的结果是 只有id不同的所有结果和上面的4类型可以互补使用,就是看你需要什么样的数据了
PS:
越来越发现有很多细节是需要去探究的,
越来越发现自己写文字真的很杂乱,
有空研究下DISTINCT的效率
突然发现mysql对于count(*)的不同处理会造成不同的结果
比如执行
SELECT count(*) FROM tablename
即使对于千万级别的数据mysql也能非常迅速的返回结果
而对于
SELECT count(*) FROM tablename WHERE…..
mysql的查询时间开始攀升
仔细查阅累下手册,发现当没有WHERE语句对于整个mysql的表进行count运算的时候
MyISAM类型的表中保存有总的行数,而当添加有WHERE限定语句的时候Mysql需要对整个表进行检索
从而得出count的数值
突然又想起来看到的不少新兴的php程序对于count的处理并没有很好的意识到这点
记录下
顺便提下mysql的DISTINCT的关键字有很多你想不到的用处
1.在count 不重复的记录的时候能用到
比如SELECT COUNT( DISTINCT id ) FROM tablename;
就是计算talbebname表中id不同的记录有多少条
2,在需要返回记录不同的id的具体值的时候可以用
比如SELECT DISTINCT id FROM tablename;
返回talbebname表中不同的id的具体的值
3.上面的情况2对于需要返回mysql表中2列以上的结果时会有歧义
比如SELECT DISTINCT id, type FROM tablename;
实际上返回的是 id与type同时不相同的结果,也就是DISTINCT同时作用了两个字段,必须得id与tyoe都相同的才被排除了,与我们期望的结果不一样
4.这时候可以考虑使用group_concat函数来进行排除,不过这个mysql函数是在mysql4.1以上才支持的
5.其实还有另外一种解决方式,就是使用
SELECT id, type, count(DISTINCT id) FROM tablename
虽然这样的返回结果多了一列无用的count数据(或许你就需要这个我说的无用数据)
返回的结果是 只有id不同的所有结果和上面的4类型可以互补使用,就是看你需要什么样的数据了
PS:
越来越发现有很多细节是需要去探究的,
越来越发现自己写文字真的很杂乱,
有空研究下DISTINCT的效率
官方修理is locked:https://help.nextcloud.com/t/how-to-fix-file-is-locked-error/180356
mysql> select count(*) from oc_file_locks;
+----------+
| count(*) |
+----------+
| 99393 |
+----------+
1 row in set (0.00 sec)
DELETE FROM `oc_file_locks` WHERE 1
实践成功来自:https://blog.csdn.net/sphinx1122/article/details/110183729
故障描述:owncloud出现文件同步错误,而且一直出现owncloud server replied : locked问题,找了整个百度,没一个解决方案,直接去官网找资料,最后找到已下方法,分享下
打开owncloud 数据库
备份:oc_file_locks表(备份免错哦)
然后清空该表,客户端同步一次,故障解决
一句搞定:
以前申请了个:www.xiangdong.org 给其他人抢去了,现在访问发现返回:This URLs or Page has been blocked.
查了下:
This URLs or Page has been blocked.
中文的意思就是
这个网址或页面已被封锁
代表你所连接的这个URL(网址)不提供你相应的要求。
譬如说打开的超连接,或下载。
总结 提供下载的网页被关了
意思:URL地址或者页面被禁止。
你可以先记下你打开的这些网页地址,然后到其他人的电脑试打开这些网页。
如果别人能打开,那多半是你的杀毒软件/防火墙的设置问题了。
你可以先尝试卸载杀毒软件/防火墙,重起再打开这些网页看。
如果安装360arp防火墙之前一直是正常的,那这种情况肯定是arp防火墙设置不正确引起的,还有一个可能就是360arp防火墙跟你的杀软防火墙冲突了。先把360防火墙卸载看看能否恢复正常。
意思嘛!
这个网已关闭.
你禁止进入此网站.
冲突域(collision domain),所有直接连接在一起的,而且必须竞争以太网总线的节点都可以认为是处在同一个冲突域中,广播域(broadcast domain),广播域是一个逻辑上的计算机组,该组内的所有计算机都会收到同样的广播信息。
mysql> select count(*) from oc_file_locks;
+----------+
| count(*) |
+----------+
| 99393 |
+----------+
1 row in set (0.00 sec)
DELETE FROM `oc_file_locks` WHERE 1
实践成功来自:https://blog.csdn.net/sphinx1122/article/details/110183729
故障描述:owncloud出现文件同步错误,而且一直出现owncloud server replied : locked问题,找了整个百度,没一个解决方案,直接去官网找资料,最后找到已下方法,分享下
打开owncloud 数据库
备份:oc_file_locks表(备份免错哦)
然后清空该表,客户端同步一次,故障解决
一句搞定:
以前申请了个:www.xiangdong.org 给其他人抢去了,现在访问发现返回:This URLs or Page has been blocked.
查了下:
This URLs or Page has been blocked.
中文的意思就是
这个网址或页面已被封锁
代表你所连接的这个URL(网址)不提供你相应的要求。
譬如说打开的超连接,或下载。
总结 提供下载的网页被关了
意思:URL地址或者页面被禁止。
你可以先记下你打开的这些网页地址,然后到其他人的电脑试打开这些网页。
如果别人能打开,那多半是你的杀毒软件/防火墙的设置问题了。
你可以先尝试卸载杀毒软件/防火墙,重起再打开这些网页看。
如果安装360arp防火墙之前一直是正常的,那这种情况肯定是arp防火墙设置不正确引起的,还有一个可能就是360arp防火墙跟你的杀软防火墙冲突了。先把360防火墙卸载看看能否恢复正常。
意思嘛!
这个网已关闭.
你禁止进入此网站.
冲突域(collision domain),所有直接连接在一起的,而且必须竞争以太网总线的节点都可以认为是处在同一个冲突域中,广播域(broadcast domain),广播域是一个逻辑上的计算机组,该组内的所有计算机都会收到同样的广播信息。
摘要:嵌入式系统诞生于微型机时代,经历了漫长的独立发展的单片机道路。给嵌入式系统寻求科学的定义,必须了解嵌入式系统的发展历史,按照历史性、本质性、普遍通用性来定义嵌入式系统,并把定义与特点相区分。由于嵌入式系统应用中,对象系统的广泛性与单片机的独立发展道路,使嵌入式系统应用在客观上存在两种模式,从学科建设上,可统一成嵌入式系统应用的高低端。阅读全文
逛论坛时看到有朋友问,是否有专门教Javascript的学校,这里想想把自己的一点建议和自己3年来的前端Javascript开发的经验跟大家分享下,也给出几本个人认为不错的书来做为大家学习的参考资料。当然只是个人的经验,有什么不对的也请高手见谅和指正。
关于到培训学校学习的忠告:别说现在没有这样的学校,就是有专门的学校也不要去,因为不会有好的老师的。不要浪费你自己(很可能是你父母)的钱和时间。趁早死了这个念头。
关于培训学校的这个我想我要比一般的朋友更有发言权,因为我本人干英语培训将近2年,我很清楚培训市场的情况,你很难碰到一个好的老师。英语可能还好些,毕竟英语说得好的老师还比较多,长期跟老外泡在一起,确实对口语能力的提高很显著,但是代价是很昂贵的。而你现在要学的是Javascript,呵呵,好的前端工程师可不多!
我的个人观点,有资格和有能力的教好Javascript的老师,一定要是个好的有着丰富的前端开发经验的前端工程师。大学的老师,教授可能他们中很少有人符合这个要求,而好的前端工程师,都忙着自己的工作去了。剩下的有时间去教Javascript的人,呵呵,就不多说了。
这里也发点牢骚,我们在大学校园里学习的东西,你学的时候根本不知道这个东西有什么意义,你自己不去钻研,老师他是不会告诉你的。在培训学校,呵呵,也差不多。
如果不是一个好的前端工程师,他很难告诉你为什么我们现在提倡使用闭包把以前的全局变量放到闭包中作为闭包函数的局部变量?他也很难对Javascript变量作用域的相关知识跟你讲透彻。在Javascript里能够形成scope(作用域)的东西有哪些?为什么说全局变量是魔鬼?闭包又是怎么产生的作用域?等等这样很基础,但很重要的知识的意义,他不清楚,讲给你听,让你明白这些知识和他们的意义就更困难。
呵呵,所以我的建议,想学Javascript,还是多跟你的身边认识的朋友,特别是那些从事前端开发的工程师多交流和学习。自己要多钻研。呵呵,不认识前端工程师,就到蓝色理想来多看看(bbs.blueidea.com,记住!这可不是广告哦!),把你不清楚的问题提出来,但是我这里要说一个好的学习习惯。什么时候提问?
什么时候提问?这个也是问题吗?对的,很多人,也是很多在校学生的一个不好的学习习惯,一有问题就问别人请求帮助。我个人这个是个坏习惯。难道问问题也是个坏习惯?对的,我个人觉得,你问问题寻求别人的帮助,应该是在你自己已经动脑经思考,通过各种途径查阅相关资料都无法获取问题的最终解决办法的情况下再来提问?这样你已经对你要解决的问题做过研究,有一定了解,你可以更详细的告诉别人你想要的答案大概是什么样的,或者说你可以把你想描述的问题讲的更清楚。这样别人来解决你的问题的时候,也可以更快速的作出解答。我想你学起来,对这个问题的理解也会更深刻些。
好了,好像扯得有些远了。来谈谈怎么学习Javascript吧!先给大家泼点冷水,我想告诉你的是:Javascript要比其他的开发语言都难学好!
为什么?因为就目前来说,大家(国内甚至是国外的程序员)普遍对Javascript这门编程语言(请允许我这么说)了解和研究得不够深,至少不像大家对JAVA,C#等这样的语言了解的和研究得那么透。所以这个就引起了另一个问题,现在市面上Javascript的书籍对Javascript这门语言的讲解都不够深入和全面。当然是相对JAVA,C#这样的语言来说。所以这就导致了,学Javascript很困难。当然学任何一门编程语言,特别是学好,学精都不容易。
不过也有好的消息,就是现在大家对Javascript的重视和更深入的研究,现在Javascript书籍里讲解的内容也要比4年前质量高出太多了,可以这么说,你现在开始Javascript正是时候哦!呵呵!所以这里也给大家一个经验,买Javascript的书,最好不要买4年前,也就是2005年前出版的。最好买近两年出版的书。
说到这里,我想说说一个现象,随这大家近几年对Javascript的重视和研究,主要是很多传统的程序员开始学习和研究Javascript,他们把面向对象编程的思想带入到Javascript的前端开发,极大的促进了Javascript的推广和发展。这点要十分感谢他们。也许是处于这些程序员的传统的开发的思想的影响,现在我们的Javascript库如雨后春笋般的出现。
呵呵!JAVA有JAVA的库和各种各样的框架,C#也是模仿JAVA,也是有着丰富的开发库。这些库为我们的开发带来了极大的方便,这是个很不错的事情。所以这些传统的程序员在从事前端的开发的时候,也为自己编写了库。我们很熟悉的就有prototype,jQuery,YUI,Ext等等,我就不一一列举了。当然这些库的出现也为我们的前端开发带来了极大的方便,但是事情都有两面性的,在这些库的出现后,在给我们的开发带来便利的同时,也让我们的很多朋友产生对库的依赖,可能严重点的,没有库了,给他个记事本(我们姑且不提开发效率)可能就不知道如何下手了。
如果仔细想想,这个也是很可怕的事情。为什么?因为大家都不再去花心思去研究Javascript底层的知识,只是一味的在这些库的帮助下,构建那些炫目的特效(还好,这些库都是免费的)。或者干脆直接用别人写好的插件。都不知道万一这些库要是开始收费(只是瞎想想),怎么办?还有就是这些库比如有别有用心的人,在中加点什么恶意的东西,我想很难有人会从头到位把一个库研究个透。你怎么办?最严重的就是编程能力的下降,但给人的感觉是入门的门槛更底了。不要被“The Write Less, Do More”这样的广告迷惑了,因为在你加载这个库的同时,别忘了"Size of your web page is much bigger, or say the size is HUGE".
所以当大家使用这些库的时候,我希望大家不仅仅是使用者,也要用心去阅读这些库的代码,从中学习。收获会很大的,而且说不定,你会发现可个改善地方,甚至是有错误的地方。这个是很有可能的。还有就是我刚才提到的,这些库的开发者很多都是从传统的程序员转型过来,或者说是因为开发需要而开始学习Javascript,很可能会有错误。或者说受以前学习语言的影响,写的程序更像是在写其他的语言,而不是写Javascript,执行效率并不高。所以不要迷信库。
问几个问题,你清楚jQuery是怎么实现CSS(3)和XML的XPath选择器的吗?jQuery又是怎么实现eventHandle的?怎么处理其中的浏览器兼容性问题的?
如果你还不明白我提的问题,那么请仔细看看jQuery是怎么实现的吧!如果你还读不懂它,还是多看看我要给你介绍的Javascript的书吧,了解Javascript的底层和基础的知识。让自己能读懂jQuery,让自己不要jQuery也能实现Dom的拖动,让自己也能写出自己的库。当然这话我说得太大了。不过只要你是真正研究Javascript和相关的知识,你也可以做到的。
绕了这么大一圈,现在让我们正式开始吧,来介绍几本学习Javascript的书吧。(以下介绍的书都是本人自己购买阅读过的,对了我不崇洋媚外,一条真理:不要买中国人写的Javascript书)
入门的书:
《Javascript高级程序设计》:不要被“高级”这两个字吓到,这个书其实是本很不错的入门的书,因为这本书也很详细的介绍了javascript的全部内置对象和语法,并且介绍了面向对象的思想,DOM、BOM的知识,正则表达式,高级的DOM处理。Ajax的知识,还是很全面的。而且个人认为这本书对基础知识的介绍并不比其他的同类书逊色。比起《Javascript权威指南》(我当时买点的是第4版),我觉得更详细些和更清楚些。在《指南》的第4版中,我觉得那本书中讲的东西有点混乱。感觉一个知识点还没有讲清楚,就给你一个什么类,看得不明不白的。因为没有看《指南》的第五版,所以这里不推荐给大家。而且《高级程序设计》这本书要比《指南》便宜不少。《高级程序设计》中也提出了采用功能(future)探测来取代浏览器版本探测来处理脚本兼容性的处理。个人觉得《指南》有的,这本书也都说了。还有我前面提到的,这本书的作者是YAHOO的资深的前端工程师,你可以在他的网站下载到相关的代码。
《Javascript DOM 编程艺术》:我个人的感觉是学习DOM编程的经典入门书籍,作者是webstandards.org的创始人之一,书中以浅显易懂的语言,教你一步一步的来讲解DOM编程,一点点地提升网站的用户体验。书中一直强调不唐突的脚本开发,网站要向后兼容,强调网站的可访问性。这个也是大家在做前端开发时应当努力追求的,也是必须要有的开发指导思想。可惜很多的后台开发的程序员,根本没有这个概念,所以你在开发的时候,一定要给你的程序员多洗脑。呵呵!
《CSS权威指南》第三版:做前端开发,你必须要了解CSS,书中对CSS2的介绍很详细了。仔细的看吧,我每次看的时候,有会有新的收获。
《网站重构》、《CSS网站布局实录》(唯一一本推荐的国人写的书):看完了,你会知道为什么学WEB标准?你会知道前端工程师的工作很重要。
提高阶段:
《Javascript DOM 高级编程》:这本书里不光详细的介绍的DOM编程的技巧,也讲了使用面向对象编程的方法,使用命名空间来管理书中所写的开发库,在不断的学习中,你的个人DOM Javascript库也不断的充实。呵呵,就像我前面说的,你可以写出自己的库了。当然书中的代码比较松散,还不能运用到实际的企业级的开发中。但是书中对闭包的介绍和面向对象的开发思想,会使你对JS的认识又提高了一个层次,虽然对面向对象开发的讲解还不够深。
《XML技术手册》:我们知道ajax,其中X就是指的XML,所以要了解XML的相关知识,你这本书,是一定要看的。看了之后你会发现XML要了解的东西实在太多了,可能跟你了解的东西相比,你才知道点皮毛。对了,这里说下,我并不推荐你使用XML来作为你的Ajax的程序的数据的载体。为什么?因为很不经济。你先把数据转换成XML文档,然后再通过Javascript把XML文档中的数据提出来,把文档转成数据。而浏览器对XPath处理的兼容性的处理,你会很发狂的。现在我们有一个代替他的东西JSON。但是由于XML已经是很多标准的默认数据通讯载体,比如RSS等,所以你还是得掌握。
个人觉得学Javascript看这些书基本差不多了。因为在我买过其他的书(
《精通Javascript》:名字起的太玄了,书不怎么样,什么都讲了点,就是不讲他怎么用jQuery来实现那些高级功能的。
《PPK 谈 Javascript》感觉跟《精通》差不多,什么都讲点,不过多点。还有起码不像《精通》起那么臭屁的名字,作者的网站确实很推荐大家去看看,http://www.quirksmode.org/。
《CSS高级技巧》介绍了很多HACK技巧,也很有用,是本好书,就是翻译得比较烂。
《Ajax in Action》、《Ajax高级编程》介绍AJAX的内容,主要看看XMLHTTPRequest的介绍把,里面的例子,很多在《高级编程》中都看过了。
《JavaScript王者归来》我上当了,自己也SB了一回。
《JavaScript:The Good Parts(影印版)》好书,你会知道JAVASCIRPT这闷语言什么东西是好的,什么东西不好?
)中,讲的内容都是大同小异。看完这些书,你了解了Javascript的相关知识,了解了CSS(你会知道CSS都有哪些选择器),你了解了XML的知识。呵呵,基础的开发你应该都可以自己解决了。而且你对Javascript的面向对象的开发也有了了解,有着向后兼容的开发思想。显然你看完这些书,你对WEB标准也会有一个更深层次的理解。
说明:为防止我的手误,把书名打错了,今天把书的图片传了上来,这回不会买错了吧
当然,想成为一个优秀的前端工程师,你要学习的知识并不只有这些,你也要知道SEO的优化知识,因为你写的页面要对搜索引擎也要友好,要结构合理。你还要了解SQL和数据库,最好还要了解C#等后台编程的语言。两个主要原因,要全面的提高自己,而且要充分的理解面向对象的编程,这些传统语言的思想更成熟,但要知道Javascript跟这些传统的编程语言的继承机制是不一样的。所以不要用Javascript来写C#。还有一个重要的原因,你要跟后台的程序员合作,要他们更坚决的执行你的不唐突的开发思想,你必须要经常给他们洗脑。但是你说的话要让他们听得进去,他说的东西你要了解,而你最好也能给他一些有好的建议,他们才会听你的。为了我们WEB标准的开展,辛苦点就辛苦点吧!
这里要补充的就是,前端开发你要自己努力学习还有JSON和正则表达式,目前还没有很详细的介绍正则的书,然后就是AJAX程序中取代XML的JSON的数据载体,掌握JSON要比XML容易得多。最后就是大家也是我提到过很多次的闭包的使用,面向对象的开发的思想。
呵呵,最后就是多练习,把你学到知识运用到实际的开发中,常跟朋友多交流,我也希望能跟大家多交流心得。大家共同进步!
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cheng5128/archive/2009/11/04/4769721.aspx
关于到培训学校学习的忠告:别说现在没有这样的学校,就是有专门的学校也不要去,因为不会有好的老师的。不要浪费你自己(很可能是你父母)的钱和时间。趁早死了这个念头。
关于培训学校的这个我想我要比一般的朋友更有发言权,因为我本人干英语培训将近2年,我很清楚培训市场的情况,你很难碰到一个好的老师。英语可能还好些,毕竟英语说得好的老师还比较多,长期跟老外泡在一起,确实对口语能力的提高很显著,但是代价是很昂贵的。而你现在要学的是Javascript,呵呵,好的前端工程师可不多!
我的个人观点,有资格和有能力的教好Javascript的老师,一定要是个好的有着丰富的前端开发经验的前端工程师。大学的老师,教授可能他们中很少有人符合这个要求,而好的前端工程师,都忙着自己的工作去了。剩下的有时间去教Javascript的人,呵呵,就不多说了。
这里也发点牢骚,我们在大学校园里学习的东西,你学的时候根本不知道这个东西有什么意义,你自己不去钻研,老师他是不会告诉你的。在培训学校,呵呵,也差不多。
如果不是一个好的前端工程师,他很难告诉你为什么我们现在提倡使用闭包把以前的全局变量放到闭包中作为闭包函数的局部变量?他也很难对Javascript变量作用域的相关知识跟你讲透彻。在Javascript里能够形成scope(作用域)的东西有哪些?为什么说全局变量是魔鬼?闭包又是怎么产生的作用域?等等这样很基础,但很重要的知识的意义,他不清楚,讲给你听,让你明白这些知识和他们的意义就更困难。
呵呵,所以我的建议,想学Javascript,还是多跟你的身边认识的朋友,特别是那些从事前端开发的工程师多交流和学习。自己要多钻研。呵呵,不认识前端工程师,就到蓝色理想来多看看(bbs.blueidea.com,记住!这可不是广告哦!),把你不清楚的问题提出来,但是我这里要说一个好的学习习惯。什么时候提问?
什么时候提问?这个也是问题吗?对的,很多人,也是很多在校学生的一个不好的学习习惯,一有问题就问别人请求帮助。我个人这个是个坏习惯。难道问问题也是个坏习惯?对的,我个人觉得,你问问题寻求别人的帮助,应该是在你自己已经动脑经思考,通过各种途径查阅相关资料都无法获取问题的最终解决办法的情况下再来提问?这样你已经对你要解决的问题做过研究,有一定了解,你可以更详细的告诉别人你想要的答案大概是什么样的,或者说你可以把你想描述的问题讲的更清楚。这样别人来解决你的问题的时候,也可以更快速的作出解答。我想你学起来,对这个问题的理解也会更深刻些。
好了,好像扯得有些远了。来谈谈怎么学习Javascript吧!先给大家泼点冷水,我想告诉你的是:Javascript要比其他的开发语言都难学好!
为什么?因为就目前来说,大家(国内甚至是国外的程序员)普遍对Javascript这门编程语言(请允许我这么说)了解和研究得不够深,至少不像大家对JAVA,C#等这样的语言了解的和研究得那么透。所以这个就引起了另一个问题,现在市面上Javascript的书籍对Javascript这门语言的讲解都不够深入和全面。当然是相对JAVA,C#这样的语言来说。所以这就导致了,学Javascript很困难。当然学任何一门编程语言,特别是学好,学精都不容易。
不过也有好的消息,就是现在大家对Javascript的重视和更深入的研究,现在Javascript书籍里讲解的内容也要比4年前质量高出太多了,可以这么说,你现在开始Javascript正是时候哦!呵呵!所以这里也给大家一个经验,买Javascript的书,最好不要买4年前,也就是2005年前出版的。最好买近两年出版的书。
说到这里,我想说说一个现象,随这大家近几年对Javascript的重视和研究,主要是很多传统的程序员开始学习和研究Javascript,他们把面向对象编程的思想带入到Javascript的前端开发,极大的促进了Javascript的推广和发展。这点要十分感谢他们。也许是处于这些程序员的传统的开发的思想的影响,现在我们的Javascript库如雨后春笋般的出现。
呵呵!JAVA有JAVA的库和各种各样的框架,C#也是模仿JAVA,也是有着丰富的开发库。这些库为我们的开发带来了极大的方便,这是个很不错的事情。所以这些传统的程序员在从事前端的开发的时候,也为自己编写了库。我们很熟悉的就有prototype,jQuery,YUI,Ext等等,我就不一一列举了。当然这些库的出现也为我们的前端开发带来了极大的方便,但是事情都有两面性的,在这些库的出现后,在给我们的开发带来便利的同时,也让我们的很多朋友产生对库的依赖,可能严重点的,没有库了,给他个记事本(我们姑且不提开发效率)可能就不知道如何下手了。
如果仔细想想,这个也是很可怕的事情。为什么?因为大家都不再去花心思去研究Javascript底层的知识,只是一味的在这些库的帮助下,构建那些炫目的特效(还好,这些库都是免费的)。或者干脆直接用别人写好的插件。都不知道万一这些库要是开始收费(只是瞎想想),怎么办?还有就是这些库比如有别有用心的人,在中加点什么恶意的东西,我想很难有人会从头到位把一个库研究个透。你怎么办?最严重的就是编程能力的下降,但给人的感觉是入门的门槛更底了。不要被“The Write Less, Do More”这样的广告迷惑了,因为在你加载这个库的同时,别忘了"Size of your web page is much bigger, or say the size is HUGE".
所以当大家使用这些库的时候,我希望大家不仅仅是使用者,也要用心去阅读这些库的代码,从中学习。收获会很大的,而且说不定,你会发现可个改善地方,甚至是有错误的地方。这个是很有可能的。还有就是我刚才提到的,这些库的开发者很多都是从传统的程序员转型过来,或者说是因为开发需要而开始学习Javascript,很可能会有错误。或者说受以前学习语言的影响,写的程序更像是在写其他的语言,而不是写Javascript,执行效率并不高。所以不要迷信库。
问几个问题,你清楚jQuery是怎么实现CSS(3)和XML的XPath选择器的吗?jQuery又是怎么实现eventHandle的?怎么处理其中的浏览器兼容性问题的?
如果你还不明白我提的问题,那么请仔细看看jQuery是怎么实现的吧!如果你还读不懂它,还是多看看我要给你介绍的Javascript的书吧,了解Javascript的底层和基础的知识。让自己能读懂jQuery,让自己不要jQuery也能实现Dom的拖动,让自己也能写出自己的库。当然这话我说得太大了。不过只要你是真正研究Javascript和相关的知识,你也可以做到的。
绕了这么大一圈,现在让我们正式开始吧,来介绍几本学习Javascript的书吧。(以下介绍的书都是本人自己购买阅读过的,对了我不崇洋媚外,一条真理:不要买中国人写的Javascript书)
入门的书:
《Javascript高级程序设计》:不要被“高级”这两个字吓到,这个书其实是本很不错的入门的书,因为这本书也很详细的介绍了javascript的全部内置对象和语法,并且介绍了面向对象的思想,DOM、BOM的知识,正则表达式,高级的DOM处理。Ajax的知识,还是很全面的。而且个人认为这本书对基础知识的介绍并不比其他的同类书逊色。比起《Javascript权威指南》(我当时买点的是第4版),我觉得更详细些和更清楚些。在《指南》的第4版中,我觉得那本书中讲的东西有点混乱。感觉一个知识点还没有讲清楚,就给你一个什么类,看得不明不白的。因为没有看《指南》的第五版,所以这里不推荐给大家。而且《高级程序设计》这本书要比《指南》便宜不少。《高级程序设计》中也提出了采用功能(future)探测来取代浏览器版本探测来处理脚本兼容性的处理。个人觉得《指南》有的,这本书也都说了。还有我前面提到的,这本书的作者是YAHOO的资深的前端工程师,你可以在他的网站下载到相关的代码。
《Javascript DOM 编程艺术》:我个人的感觉是学习DOM编程的经典入门书籍,作者是webstandards.org的创始人之一,书中以浅显易懂的语言,教你一步一步的来讲解DOM编程,一点点地提升网站的用户体验。书中一直强调不唐突的脚本开发,网站要向后兼容,强调网站的可访问性。这个也是大家在做前端开发时应当努力追求的,也是必须要有的开发指导思想。可惜很多的后台开发的程序员,根本没有这个概念,所以你在开发的时候,一定要给你的程序员多洗脑。呵呵!
《CSS权威指南》第三版:做前端开发,你必须要了解CSS,书中对CSS2的介绍很详细了。仔细的看吧,我每次看的时候,有会有新的收获。
《网站重构》、《CSS网站布局实录》(唯一一本推荐的国人写的书):看完了,你会知道为什么学WEB标准?你会知道前端工程师的工作很重要。
提高阶段:
《Javascript DOM 高级编程》:这本书里不光详细的介绍的DOM编程的技巧,也讲了使用面向对象编程的方法,使用命名空间来管理书中所写的开发库,在不断的学习中,你的个人DOM Javascript库也不断的充实。呵呵,就像我前面说的,你可以写出自己的库了。当然书中的代码比较松散,还不能运用到实际的企业级的开发中。但是书中对闭包的介绍和面向对象的开发思想,会使你对JS的认识又提高了一个层次,虽然对面向对象开发的讲解还不够深。
《XML技术手册》:我们知道ajax,其中X就是指的XML,所以要了解XML的相关知识,你这本书,是一定要看的。看了之后你会发现XML要了解的东西实在太多了,可能跟你了解的东西相比,你才知道点皮毛。对了,这里说下,我并不推荐你使用XML来作为你的Ajax的程序的数据的载体。为什么?因为很不经济。你先把数据转换成XML文档,然后再通过Javascript把XML文档中的数据提出来,把文档转成数据。而浏览器对XPath处理的兼容性的处理,你会很发狂的。现在我们有一个代替他的东西JSON。但是由于XML已经是很多标准的默认数据通讯载体,比如RSS等,所以你还是得掌握。
个人觉得学Javascript看这些书基本差不多了。因为在我买过其他的书(
《精通Javascript》:名字起的太玄了,书不怎么样,什么都讲了点,就是不讲他怎么用jQuery来实现那些高级功能的。
《PPK 谈 Javascript》感觉跟《精通》差不多,什么都讲点,不过多点。还有起码不像《精通》起那么臭屁的名字,作者的网站确实很推荐大家去看看,http://www.quirksmode.org/。
《CSS高级技巧》介绍了很多HACK技巧,也很有用,是本好书,就是翻译得比较烂。
《Ajax in Action》、《Ajax高级编程》介绍AJAX的内容,主要看看XMLHTTPRequest的介绍把,里面的例子,很多在《高级编程》中都看过了。
《JavaScript王者归来》我上当了,自己也SB了一回。
《JavaScript:The Good Parts(影印版)》好书,你会知道JAVASCIRPT这闷语言什么东西是好的,什么东西不好?
)中,讲的内容都是大同小异。看完这些书,你了解了Javascript的相关知识,了解了CSS(你会知道CSS都有哪些选择器),你了解了XML的知识。呵呵,基础的开发你应该都可以自己解决了。而且你对Javascript的面向对象的开发也有了了解,有着向后兼容的开发思想。显然你看完这些书,你对WEB标准也会有一个更深层次的理解。
说明:为防止我的手误,把书名打错了,今天把书的图片传了上来,这回不会买错了吧
当然,想成为一个优秀的前端工程师,你要学习的知识并不只有这些,你也要知道SEO的优化知识,因为你写的页面要对搜索引擎也要友好,要结构合理。你还要了解SQL和数据库,最好还要了解C#等后台编程的语言。两个主要原因,要全面的提高自己,而且要充分的理解面向对象的编程,这些传统语言的思想更成熟,但要知道Javascript跟这些传统的编程语言的继承机制是不一样的。所以不要用Javascript来写C#。还有一个重要的原因,你要跟后台的程序员合作,要他们更坚决的执行你的不唐突的开发思想,你必须要经常给他们洗脑。但是你说的话要让他们听得进去,他说的东西你要了解,而你最好也能给他一些有好的建议,他们才会听你的。为了我们WEB标准的开展,辛苦点就辛苦点吧!
这里要补充的就是,前端开发你要自己努力学习还有JSON和正则表达式,目前还没有很详细的介绍正则的书,然后就是AJAX程序中取代XML的JSON的数据载体,掌握JSON要比XML容易得多。最后就是大家也是我提到过很多次的闭包的使用,面向对象的开发的思想。
呵呵,最后就是多练习,把你学到知识运用到实际的开发中,常跟朋友多交流,我也希望能跟大家多交流心得。大家共同进步!
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cheng5128/archive/2009/11/04/4769721.aspx
Portotype虽然是强大的,和script.aculo.us结合可以做出很多完美的效果,可是它里面有太多我不想用的代码,或许这是我后面选择 mootools的主要原因,我只是想选择性的打包。其实当时我也很想用一下jquery,仔细对比了一下,我还是觉得mootools更加的适合于我。有比较,才有机会去选择,我想从下面5个方面讨论一下。
可读性VS简洁
在网上,很多人把mootools比作java,把jquery比作perl,jquery的口号是“write less,do more”,或许就是这个目标造就了它的诡异。我觉得和mootools代码比起来,我看jquery的代码更加的吃力,有时候一行代码需要看半个小时才可以搞懂它的意思,这在mootools中是不存在的。如果你本身是一个崇尚代码简洁的人,或许jquery是你的很好的选择。虽然jquery的性能也稍高一点,不过,我觉得可读性更重要,所以我觉得mootools更加适合我。
重复的制造轮子VS拿来主义
在所有的js框架中,我始终觉得Ext框架是“拿来主义者”们最好的选择。和ext比起来,jquery UI 其实做的不怎么样,但是jquery有很多的插件。几乎你看到的网页效果,在jquery的插件库中都可以找到,为了避免重复的制造轮子,或许 jquery是一个不错的选择。而我觉得重复的制造轮子会让我更加的熟悉制作的工艺,从中了解每种框架不同之处和各自的优势,所以,我没事就修改一下 jquery框架中的插件,让他们用mootools的方式去运行。我之所以在大学阶段对面向对象理解不够深刻,主要是各种IDE工具让我成了IT民工。现在,我不能再做肤浅的拿来主义者,好多的代码因为性能问题,必须手写。
团队协作的成果VS天才的思维
jquery是程序天才JOHN RESIG的作品,mootools是一个团队的作品,有时候天才的思维很难读懂,我并不是想为此而逃避不去学习,主要是我希望用一个灵感汇聚的js框架。值得肯定的是:jquery的很多代码都写的比mootools优雅一些,简洁一点,注意这里是简洁而不是简单。团队中,思想的碰撞要多一些,产品的尝起来也就更清淡一些。我希望循序渐进的去理解js,所以我对自己不能用猛药,mootools像一碗粥,而不是参汤。
项目VS个人学习
其实在我们产品部的项目中用的是ExtJs,这个框架帮你做了所有的事情,你基本只管调用就可以了。后来看一下,或许使用jquery UI会好一点,主要是好多代码自己都可以去尝试写一下。如果你在做项目,强烈建议使用jquery,因为很多他的插件可以帮你按照项目的工期完成任务,当然这是第一步,后面或许因为性能问题,你需要修改很多地方的代码。如果是产品部慢慢的在一个框架上有积累的话,或许不会有这样的问题存在,我是建议一个产品部能够持续的学习一个框架,无论是哪一个,精通的过程是痛苦的,可是如果不精通,整个产品都是痛苦的。
完成任务VS希望成为高手
前面已经说过:如果想更快的完成任务,你需要选择jquery,如果想痛苦的积累,选择mootools或许会更好。才开始使用mootools1.2的时候,我几乎崩溃,因为我写的1.1的代码都不能用了,后来没事看了一下1.2的源代码,无论是在功能上还是在性能上,这样的改动是有必要的。同时,也赞扬一下mootools团队的勇气,和老版本的不兼容真的会让很多人抓狂。一点点的积累,一点点的领悟JavaScript,mootools是一个不错的选择。
可读性VS简洁
在网上,很多人把mootools比作java,把jquery比作perl,jquery的口号是“write less,do more”,或许就是这个目标造就了它的诡异。我觉得和mootools代码比起来,我看jquery的代码更加的吃力,有时候一行代码需要看半个小时才可以搞懂它的意思,这在mootools中是不存在的。如果你本身是一个崇尚代码简洁的人,或许jquery是你的很好的选择。虽然jquery的性能也稍高一点,不过,我觉得可读性更重要,所以我觉得mootools更加适合我。
重复的制造轮子VS拿来主义
在所有的js框架中,我始终觉得Ext框架是“拿来主义者”们最好的选择。和ext比起来,jquery UI 其实做的不怎么样,但是jquery有很多的插件。几乎你看到的网页效果,在jquery的插件库中都可以找到,为了避免重复的制造轮子,或许 jquery是一个不错的选择。而我觉得重复的制造轮子会让我更加的熟悉制作的工艺,从中了解每种框架不同之处和各自的优势,所以,我没事就修改一下 jquery框架中的插件,让他们用mootools的方式去运行。我之所以在大学阶段对面向对象理解不够深刻,主要是各种IDE工具让我成了IT民工。现在,我不能再做肤浅的拿来主义者,好多的代码因为性能问题,必须手写。
团队协作的成果VS天才的思维
jquery是程序天才JOHN RESIG的作品,mootools是一个团队的作品,有时候天才的思维很难读懂,我并不是想为此而逃避不去学习,主要是我希望用一个灵感汇聚的js框架。值得肯定的是:jquery的很多代码都写的比mootools优雅一些,简洁一点,注意这里是简洁而不是简单。团队中,思想的碰撞要多一些,产品的尝起来也就更清淡一些。我希望循序渐进的去理解js,所以我对自己不能用猛药,mootools像一碗粥,而不是参汤。
项目VS个人学习
其实在我们产品部的项目中用的是ExtJs,这个框架帮你做了所有的事情,你基本只管调用就可以了。后来看一下,或许使用jquery UI会好一点,主要是好多代码自己都可以去尝试写一下。如果你在做项目,强烈建议使用jquery,因为很多他的插件可以帮你按照项目的工期完成任务,当然这是第一步,后面或许因为性能问题,你需要修改很多地方的代码。如果是产品部慢慢的在一个框架上有积累的话,或许不会有这样的问题存在,我是建议一个产品部能够持续的学习一个框架,无论是哪一个,精通的过程是痛苦的,可是如果不精通,整个产品都是痛苦的。
完成任务VS希望成为高手
前面已经说过:如果想更快的完成任务,你需要选择jquery,如果想痛苦的积累,选择mootools或许会更好。才开始使用mootools1.2的时候,我几乎崩溃,因为我写的1.1的代码都不能用了,后来没事看了一下1.2的源代码,无论是在功能上还是在性能上,这样的改动是有必要的。同时,也赞扬一下mootools团队的勇气,和老版本的不兼容真的会让很多人抓狂。一点点的积累,一点点的领悟JavaScript,mootools是一个不错的选择。
对系统管理员来说,平时的工作重心应该集中在维护系统正常运转,能够正常提供服务上,这里往往牵涉到一个数据备份的问题,在我所了解
的情况中,有80%的系统管理员不是太关心自己服务器的安全性,但往往对备分镜像的技术相当感兴趣,但由于商业产品的软硬件价格都相当高
昂,因此往往会选择自由软件。这里准备介绍的rsync就是这样的软件,它可以满足绝大多数要求不是特别高的备份需求。阅读全文
的情况中,有80%的系统管理员不是太关心自己服务器的安全性,但往往对备分镜像的技术相当感兴趣,但由于商业产品的软硬件价格都相当高
昂,因此往往会选择自由软件。这里准备介绍的rsync就是这样的软件,它可以满足绝大多数要求不是特别高的备份需求。阅读全文
转自:温德馨的博客,哈哈,向东的博客早就O了,链接还是xiangdong.org,哎,我转了一席,他对mysql的io调度和DAS、NAS、SAN存储系统完全分析都有研究和关注,哈哈
一直对JS的跨域概念很迷惑,记得是在刚学ajax的时候才了解了一下这个概念,后来就再没有接触。主要工作上是做PHP为主,前端的东西几乎不需要插手。今天看了膘叔的一篇文章《孟宪会之AJAX(XMLHttpRequest)进行跨域请求方法详解》,一直是知道跨域会存在问题,但是自己就没有动过手体验一下具体会造成什么问题,于是决定试验一下。在blog服务器上写了个test.php测试脚本
<?php
$data = array('status' => 1, ‘msg’ => ‘hello’);
echo json_encode($data);
?></p>
<p>
前端测试页面
<script>
var xhr = new XMLHttpRequest();
var url = "http://jackywdx.cn/test.php";
function test(){
if(xhr)
{
xhr.open('GET', url, true);
xhr.onreadystatechange = handler;
xhr.send();
}
}
function handler(evtxhr)
{
if(xhr.readyState == 4){
if(xhr.status == 200){
var re = xhr.responseText;
alert(re);
}else{
alert('status not 200');
alert(xhr.status);
}
}else{
alert('readyState not 4');
alert(xhr.readyState);
}
}</p>
<p><body onload="test()">
hello
</body>
在本地访问,http://test.cn/test.html 结果是失败,没有alert出responseText; 在test.php文件里面增加一句: header(”Access-Control-Allow-Origin:http://test.cn”); 这样就可以了。我用的FF版本是3.5.7,所以支持这个Access-Control-Allow-Origin HTTP头部参数。用HTTPFOX抓包看到结果:
(Request-Line)
GET /test.php HTTP/1.1
Host jackywdx.cn
User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
Connection keep-alive
Referer http://test.cn/test.html
Origin http://test.cn
(Status-Line) HTTP/1.1 200 OK
Server nginx/0.7.61
Date Fri, 29 Jan 2010 02:43:39 GMT
Content-Type text/html
Transfer-Encoding chunked
Connection close
X-Powered-By PHP/5.2.6
Access-Control-Allow-Origin http://test.cn
Author jackywdx
X-Via US_RASHOST_VPS
Content-Encoding gzip
解决JS跨域问题还有一些解决办法:
如果是同一主域的话可以设置document.domain
另外还可以通过flash来作为中转角色,flash跨域可以通过crossdomain.xml来解决,不过这种方法速度会比较慢。毕竟多了一层中间层。
还有一种比较土的方法就是在相册的域下面做一个同样的接口-.-
一直对JS的跨域概念很迷惑,记得是在刚学ajax的时候才了解了一下这个概念,后来就再没有接触。主要工作上是做PHP为主,前端的东西几乎不需要插手。今天看了膘叔的一篇文章《孟宪会之AJAX(XMLHttpRequest)进行跨域请求方法详解》,一直是知道跨域会存在问题,但是自己就没有动过手体验一下具体会造成什么问题,于是决定试验一下。在blog服务器上写了个test.php测试脚本
<?php
$data = array('status' => 1, ‘msg’ => ‘hello’);
echo json_encode($data);
?></p>
<p>
前端测试页面
<script>
var xhr = new XMLHttpRequest();
var url = "http://jackywdx.cn/test.php";
function test(){
if(xhr)
{
xhr.open('GET', url, true);
xhr.onreadystatechange = handler;
xhr.send();
}
}
function handler(evtxhr)
{
if(xhr.readyState == 4){
if(xhr.status == 200){
var re = xhr.responseText;
alert(re);
}else{
alert('status not 200');
alert(xhr.status);
}
}else{
alert('readyState not 4');
alert(xhr.readyState);
}
}</p>
<p><body onload="test()">
hello
</body>
在本地访问,http://test.cn/test.html 结果是失败,没有alert出responseText; 在test.php文件里面增加一句: header(”Access-Control-Allow-Origin:http://test.cn”); 这样就可以了。我用的FF版本是3.5.7,所以支持这个Access-Control-Allow-Origin HTTP头部参数。用HTTPFOX抓包看到结果:
(Request-Line)
GET /test.php HTTP/1.1
Host jackywdx.cn
User-Agent Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language zh-cn,zh;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
Connection keep-alive
Referer http://test.cn/test.html
Origin http://test.cn
(Status-Line) HTTP/1.1 200 OK
Server nginx/0.7.61
Date Fri, 29 Jan 2010 02:43:39 GMT
Content-Type text/html
Transfer-Encoding chunked
Connection close
X-Powered-By PHP/5.2.6
Access-Control-Allow-Origin http://test.cn
Author jackywdx
X-Via US_RASHOST_VPS
Content-Encoding gzip
解决JS跨域问题还有一些解决办法:
如果是同一主域的话可以设置document.domain
另外还可以通过flash来作为中转角色,flash跨域可以通过crossdomain.xml来解决,不过这种方法速度会比较慢。毕竟多了一层中间层。
还有一种比较土的方法就是在相册的域下面做一个同样的接口-.-
if (function_exists("imagecreatetruecolor")){
//resize picture
$new = imagecreatetruecolor($intWidth, $intHeight);
imagealphablending($new,false);
ImageCopyResampled($new, $img, 0, 0, 0, 0, $intWidth, $intHeight, $arrImageInfo["width"], $arrImageInfo["height"]);
imagesavealpha($new,true);
} else {
//resize picture
$new = imagecreate($intWidth, $intHeight);
imagealphablending($new,false);
ImageCopyResized($new, $img, 0, 0, 0, 0,$intWidth, $intHeight, $arrImageInfo["width"], $arrImageInfo["height"]);
imagesavealpha($new,true);
}
参考:http://hi.baidu.com/fanfan201314/item/2d4857de01f3cce93cc2cbff
做web开发的朋友都清楚,js程序的调试是相当郁闷的,因为首先这种语言语法比较灵活,它是一种弱类型的脚本语言,很多错误是无法控制的,这些不谈,最痛苦的是没有什么好的调试工具,现在的情况比以前稍好,在Firefox下还有firebug,这的确是一个不错的js调试工具,但在IE下使用就很麻烦,而且效果很不好,鄙人一直苦于寻找一个很好的IE下的js调试工具,能够自动捕获错误,并定位位置和原因,没想到今天竟在无意中寻找到了这么个好工具,不敢私藏,共享出来,希望能为各位web开发者带来方便
这个工具的名字叫Companion.JS,请注意,这可不是一个js文件,而是一个名字,它是作为ie的插件来安装使用的,而且需要结合 Microsoft Script Debugger使用,通过安装这个工具,但页面出现错误时会在左上角弹出一个小错误提示,点击会在IE下面显示出一个错误控制台,就如FF下的 firebug控制台一样。错误信息提示很详细。
如下是官网的一个错误提示示例图:
点击在新窗口中浏览此图片
官网地址:http://www.my-debugbar.com/wiki/CompanionJS/HomePage
具体使用方法为:
1、先下载Companion.JS安装文件,然后安装。
2、下载安装Microsoft Script Debugger,如果您的机器已经安装过了就可以免过这一步。
3、打开IE菜单“工具”–“Internet选项”–“高级”,找到“禁用脚本调试(Internet Explorer)”和“禁用脚本调试(在Internet Explorer之外)”,将两个选项前面的对钩都去掉,然后重启IE。
4、最后,测试安装成功于否:
在Ie中输入:http://www.my-debugbar.com/wiki/uploads/CompanionJS/dummy.htm,然后点击click me链接,如果左上角弹出一个小错误提示或下面控制台出现了错误信息提示,就说明您已经安装成功了。
如果没有安装Microsoft Script Debugger是只提示不会有黄色标识的:
提示:Microsoft Script Debugger下载可到MS官网(需要经过MS的操作系统正版验证):http://www.microsoft.com/downloads /details.aspx?displaylang=zh-cn&FamilyID=E606E71F-BA7F-471E-A57D- F2216D81EC3D#filelist或到baidu里输入“Microsoft Script Debugger 下载”寻找一下。
求Microsoft Script Debugger中文版的下载地址:
是这个吗 Windows Script Debugger
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=E606E71F-BA7F-471E-A57D-F2216D81EC3D
继续追问: 对,就是这个。
Microsoft DownLoad Url:
http://www.microsoft.com/zh-cn/download/details.aspx?id=23992
---------------------------------------------------------------------------------------------------------------------------------------------------------------
IE下使用firebug:
firebug官网:https://getfirebug.com/
把下面这段代码复制替换一个自己新建立的收藏Url即可,然后需要时再运行一下收藏夹,进而按F12调出来即可,如不运行收藏夹则是IE自带的那个。
做web开发的朋友都清楚,js程序的调试是相当郁闷的,因为首先这种语言语法比较灵活,它是一种弱类型的脚本语言,很多错误是无法控制的,这些不谈,最痛苦的是没有什么好的调试工具,现在的情况比以前稍好,在Firefox下还有firebug,这的确是一个不错的js调试工具,但在IE下使用就很麻烦,而且效果很不好,鄙人一直苦于寻找一个很好的IE下的js调试工具,能够自动捕获错误,并定位位置和原因,没想到今天竟在无意中寻找到了这么个好工具,不敢私藏,共享出来,希望能为各位web开发者带来方便
这个工具的名字叫Companion.JS,请注意,这可不是一个js文件,而是一个名字,它是作为ie的插件来安装使用的,而且需要结合 Microsoft Script Debugger使用,通过安装这个工具,但页面出现错误时会在左上角弹出一个小错误提示,点击会在IE下面显示出一个错误控制台,就如FF下的 firebug控制台一样。错误信息提示很详细。
如下是官网的一个错误提示示例图:
点击在新窗口中浏览此图片
官网地址:http://www.my-debugbar.com/wiki/CompanionJS/HomePage
具体使用方法为:
1、先下载Companion.JS安装文件,然后安装。
2、下载安装Microsoft Script Debugger,如果您的机器已经安装过了就可以免过这一步。
3、打开IE菜单“工具”–“Internet选项”–“高级”,找到“禁用脚本调试(Internet Explorer)”和“禁用脚本调试(在Internet Explorer之外)”,将两个选项前面的对钩都去掉,然后重启IE。
4、最后,测试安装成功于否:
在Ie中输入:http://www.my-debugbar.com/wiki/uploads/CompanionJS/dummy.htm,然后点击click me链接,如果左上角弹出一个小错误提示或下面控制台出现了错误信息提示,就说明您已经安装成功了。
如果没有安装Microsoft Script Debugger是只提示不会有黄色标识的:
提示:Microsoft Script Debugger下载可到MS官网(需要经过MS的操作系统正版验证):http://www.microsoft.com/downloads /details.aspx?displaylang=zh-cn&FamilyID=E606E71F-BA7F-471E-A57D- F2216D81EC3D#filelist或到baidu里输入“Microsoft Script Debugger 下载”寻找一下。
求Microsoft Script Debugger中文版的下载地址:
是这个吗 Windows Script Debugger
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=E606E71F-BA7F-471E-A57D-F2216D81EC3D
继续追问: 对,就是这个。
Microsoft DownLoad Url:
http://www.microsoft.com/zh-cn/download/details.aspx?id=23992
---------------------------------------------------------------------------------------------------------------------------------------------------------------
IE下使用firebug:
firebug官网:https://getfirebug.com/
把下面这段代码复制替换一个自己新建立的收藏Url即可,然后需要时再运行一下收藏夹,进而按F12调出来即可,如不运行收藏夹则是IE自带的那个。
说起正则表达式,可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch和Walter Pitts这两位神经生理学家研究出一种数学方式来描述这些神经网络。
1956年,一位叫Stephen Kleene的美国数学家在McCulloch和Pitts早期工作的基础上,发表了一篇标题为“神经网事件的表示法”的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式,因此采用“正则表达式”这个术语。
随后,发现可以将这一工作应用于使用Ken Thompson的计算搜索算法的一些早期研究,Ken Thompson是Unix的主要发明人。正则表达式的第一个实用应用程序就是Unix中的qed编辑器。
这个专题主要是为了提高大家对正则表达式的认识和高级的使用。
1 使用正则表达式来检测HTML是否关闭
解释:
/<([a-zA-Z0-9]+)\\s*[^\\/>]*>/这个模式是用来匹配HTML的标记(如:<head>、<div>、<div id="main">等等,但是除了<br/>这种)的,并且在$start_tags保持着标签的名字(如:head、div等)。而/<\\/([a-zA-Z0-9]+)>/这个模式是用来匹配闭合的HTML标记(如:</head>,</div>等)的。并且在$end_tags中保持这闭合的标签名。然后我们用count($start_tags[1]) != count($end_tags[1])这个条件语句来判断开始的标记跟闭合的标记是否相等,不相等就说明没闭合。最后用in_array($start_tags[1][$i], $end_tags[1])来判断开始标跟闭合的标记是否相等。至此,我们就完成了HTML的匹配了!
2 匹配E-mail格式
解释:
不要被/^[\w\d!#$%&'*+-\/=?^`{|}~]+(\.[\w\d!#$%&'*+-\/=?^`{|}~]+)*@([a-z\d][-a-z\d]*[a-z\d]\.)+[a-z][-a-z\d]*[a-z]$/这条模式给吓跑了,其实也很简单的。前部分[\w\d!#$%&'*+-\/=?^`{|}~]+(\.[\w\d!#$%&'*+-\/=?^`{|}~]+)*只是匹配符合RFC-2882标准的E-mail地址允许出现的字符,就是英文字母,数字跟一些符号,有兴趣可以查询RFC-2882手册,而([a-z\d][-a-z\d]*[a-z\d]\.)+就是匹配HOST的。最后[a-z][-a-z\d]*[a-z]就是匹配顶级域名的(如:.com、.org)。
3 非贪心模式
有时候使用正则表达式的时候,你会发现有以下的问题:
很惊奇的你会发现匹配的是这样的内容"hello", Jack say: "Hi",而不是"hello"和"Hi"。这就是贪心匹配引起的。在贪心匹配中,正则表达式会尽可能的匹配最多的字符,所以出现了第一种情况,但是我们想要的是第二种情况,那我们要怎么做呢?
我们可以使用非贪心匹配,将刚才的模式改为/".*?"/这样就可以看见我们想要的结果了。*?这个就是非贪心匹配模式。还有另外一种就是+?。
*?:前面的字符可以出现任意多次,但是遇到*?后的一个字符即停止匹配。
+?:前面的字符可以出现一次或者多次,但是遇到+?后的一个字符即停止匹配。
4 检测一个用户密码是否安全
解释:
在本例中,我们使用了/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}/模式来匹配我们的密码。在这个模式中,我们使用了正则表达式中的前瞻模式(?=)。(?=.*[0-9])这个是匹配密码中有数字,而(?=.*[a-z])是匹配密码中有小写字母,最后(?=.*[A-Z])就是匹配密码中有大写字母。而.{8,16}这个就是匹配密码是由8至16个字符组成的。那么我们的密码就需要有数字,大写字母和小写字母组成的就属于安全的密码了~
5 匹配一个网站中的所有链接
在这个例子中,我们想用file_get_contents来取得一个网页的内容。然后用str_replace("\n", "", $html)把所有的换行去掉。再用preg_replace('/<a/i', "\n<a", $html)和preg_replace('/<\/a>/', "</a>\n", $html)来把所有的<a href=".....">.....</a>模式另起一行。最后就用preg_match_all('/<a\s*.*>.*?<\/a>/', $html, $matches)匹配链接模式。/<a\s*.*>.*?<\/a>/就是匹配<a href=".....">.....</a>这种模式的正则表达式。那我们为什么要把<a href=".....">.....</a>链接另起一行呢??因为在/<a\s*.*>.*?<\/a>/模式中,.*是不能匹配换行的,所以就如<a>和</a>不在同一行就不能匹配了!!所以我们要这样做!
1956年,一位叫Stephen Kleene的美国数学家在McCulloch和Pitts早期工作的基础上,发表了一篇标题为“神经网事件的表示法”的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式,因此采用“正则表达式”这个术语。
随后,发现可以将这一工作应用于使用Ken Thompson的计算搜索算法的一些早期研究,Ken Thompson是Unix的主要发明人。正则表达式的第一个实用应用程序就是Unix中的qed编辑器。
这个专题主要是为了提高大家对正则表达式的认识和高级的使用。
1 使用正则表达式来检测HTML是否关闭
function check_html($html) {
preg_match_all("/<([a-zA-Z0-9]+)\\s*[^\\/>]*>/",$html,$start_tags);
preg_match_all("/<\\/([a-zA-Z0-9]+)>/", $html, $end_tags);
if(count($start_tags[1]) != count($end_tags[1])) return false;
for($i = 0; $i < count($start_tags[1]); $i++) {
if(!in_array($start_tags[1][$i], $end_tags[1])) return false;
}
return true;
}
preg_match_all("/<([a-zA-Z0-9]+)\\s*[^\\/>]*>/",$html,$start_tags);
preg_match_all("/<\\/([a-zA-Z0-9]+)>/", $html, $end_tags);
if(count($start_tags[1]) != count($end_tags[1])) return false;
for($i = 0; $i < count($start_tags[1]); $i++) {
if(!in_array($start_tags[1][$i], $end_tags[1])) return false;
}
return true;
}
解释:
/<([a-zA-Z0-9]+)\\s*[^\\/>]*>/这个模式是用来匹配HTML的标记(如:<head>、<div>、<div id="main">等等,但是除了<br/>这种)的,并且在$start_tags保持着标签的名字(如:head、div等)。而/<\\/([a-zA-Z0-9]+)>/这个模式是用来匹配闭合的HTML标记(如:</head>,</div>等)的。并且在$end_tags中保持这闭合的标签名。然后我们用count($start_tags[1]) != count($end_tags[1])这个条件语句来判断开始的标记跟闭合的标记是否相等,不相等就说明没闭合。最后用in_array($start_tags[1][$i], $end_tags[1])来判断开始标跟闭合的标记是否相等。至此,我们就完成了HTML的匹配了!
2 匹配E-mail格式
function check_email($email) {
if(preg_match("/^[\w\d!#$%&'*+-\/=?^`{|}~]+(\.[\w\d!#$%&'*+-\/=?^`{|}~]+)*@([a-z\d][-a-z\d]*[a-z\d]\.)+[a-z][-a-z\d]*[a-z]$/", $eamil)) return true;
return false;
}
if(preg_match("/^[\w\d!#$%&'*+-\/=?^`{|}~]+(\.[\w\d!#$%&'*+-\/=?^`{|}~]+)*@([a-z\d][-a-z\d]*[a-z\d]\.)+[a-z][-a-z\d]*[a-z]$/", $eamil)) return true;
return false;
}
解释:
不要被/^[\w\d!#$%&'*+-\/=?^`{|}~]+(\.[\w\d!#$%&'*+-\/=?^`{|}~]+)*@([a-z\d][-a-z\d]*[a-z\d]\.)+[a-z][-a-z\d]*[a-z]$/这条模式给吓跑了,其实也很简单的。前部分[\w\d!#$%&'*+-\/=?^`{|}~]+(\.[\w\d!#$%&'*+-\/=?^`{|}~]+)*只是匹配符合RFC-2882标准的E-mail地址允许出现的字符,就是英文字母,数字跟一些符号,有兴趣可以查询RFC-2882手册,而([a-z\d][-a-z\d]*[a-z\d]\.)+就是匹配HOST的。最后[a-z][-a-z\d]*[a-z]就是匹配顶级域名的(如:.com、.org)。
3 非贪心模式
有时候使用正则表达式的时候,你会发现有以下的问题:
preg_match('/".*"/', 'Tony say:"hello", Jack say: "Hi"', $matches);
print_r($matches);
print_r($matches);
很惊奇的你会发现匹配的是这样的内容"hello", Jack say: "Hi",而不是"hello"和"Hi"。这就是贪心匹配引起的。在贪心匹配中,正则表达式会尽可能的匹配最多的字符,所以出现了第一种情况,但是我们想要的是第二种情况,那我们要怎么做呢?
我们可以使用非贪心匹配,将刚才的模式改为/".*?"/这样就可以看见我们想要的结果了。*?这个就是非贪心匹配模式。还有另外一种就是+?。
*?:前面的字符可以出现任意多次,但是遇到*?后的一个字符即停止匹配。
+?:前面的字符可以出现一次或者多次,但是遇到+?后的一个字符即停止匹配。
4 检测一个用户密码是否安全
function is_good_pw($pw) {
if(preg_match('/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}/', $pw)) {
return true;
}
return false;
}
if(preg_match('/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}/', $pw)) {
return true;
}
return false;
}
解释:
在本例中,我们使用了/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}/模式来匹配我们的密码。在这个模式中,我们使用了正则表达式中的前瞻模式(?=)。(?=.*[0-9])这个是匹配密码中有数字,而(?=.*[a-z])是匹配密码中有小写字母,最后(?=.*[A-Z])就是匹配密码中有大写字母。而.{8,16}这个就是匹配密码是由8至16个字符组成的。那么我们的密码就需要有数字,大写字母和小写字母组成的就属于安全的密码了~
5 匹配一个网站中的所有链接
function get_links($link) {
$html = file_get_contents($link);
$html = str_replace("\n", "", $html);
$html = preg_replace('/<a/i', "\n<a", $html);
$html = preg_replace('/<\/a>/', "</a>\n", $html);
preg_match_all('/<a\s*.*>.*?<\/a>/', $html, $matches);
return($matches);
}
$html = file_get_contents($link);
$html = str_replace("\n", "", $html);
$html = preg_replace('/<a/i', "\n<a", $html);
$html = preg_replace('/<\/a>/', "</a>\n", $html);
preg_match_all('/<a\s*.*>.*?<\/a>/', $html, $matches);
return($matches);
}
在这个例子中,我们想用file_get_contents来取得一个网页的内容。然后用str_replace("\n", "", $html)把所有的换行去掉。再用preg_replace('/<a/i', "\n<a", $html)和preg_replace('/<\/a>/', "</a>\n", $html)来把所有的<a href=".....">.....</a>模式另起一行。最后就用preg_match_all('/<a\s*.*>.*?<\/a>/', $html, $matches)匹配链接模式。/<a\s*.*>.*?<\/a>/就是匹配<a href=".....">.....</a>这种模式的正则表达式。那我们为什么要把<a href=".....">.....</a>链接另起一行呢??因为在/<a\s*.*>.*?<\/a>/模式中,.*是不能匹配换行的,所以就如<a>和</a>不在同一行就不能匹配了!!所以我们要这样做!
function huanImg(num)
{
var imgsrc = $('#small_' + num).attr('lang');
$('#list_big').attr('src',imgsrc);
}
{
var imgsrc = $('#small_' + num).attr('lang');
$('#list_big').attr('src',imgsrc);
}
左边小图列表:
<li><a href="javascript:void(0)" onclick = "huanImg('1')"><img id="small_1" src="/data/72/mini_372647693_uploadFile1_20100202_122357_1.jpg" lang="/data/72/372647693_uploadFile1_20100202_122357_1.jpg" /></a></li>
<li><a href="javascript:void(0)" onclick = "huanImg('2')"><img id="small_2" src="/data/72/mini_372647693_uploadFile2_20100202_122357_1.jpg" lang="/data/72/372647693_uploadFile2_20100202_122357_1.jpg" /></a></li>
<li><a href="javascript:void(0)" onclick = "huanImg('3')"><img id="small_3" src="/data/72/mini_372647693_uploadFile3_20100202_122357_1.jpg" lang="/data/72/372647693_uploadFile3_20100202_122357_1.jpg" /></a>
右边大图展现:
<div class="center_img"><img width="307" height="306" src="/data/72/372647693_uploadFile1_20100202_122357_1.jpg" id="list_big"></div>
[个人原创]PHP时间范围判断的最简单的方法,PHP时分秒大小
Php/Js/Shell/Go jackxiang 2010-2-1 21:28
常常需要比较时间,如几点比几点大,这儿用一个简单的方法比较:
需要比较:
二月七日凌晨到下午二点的时间不让用户领取奖品的比较,如下:
$nowDate=mktime(date('H'),date('i'),date('s'),date('m'),date('d'),date('Y'));
$day = date("d");
if($day == 7)
{
//第一天 2月7日
$forbidden_begin = mktime(0,0,0,2,7,2010);//开始时间
$forbidden_end = mktime(14,0,0,2,7,2010);//结束时间
if(($nowDate>=$forbidden_begin)&&($nowDate<=$forbidden_end))
{
return array('code'=>-1,'awardleft'=>0,'message'=>'兑换时间已过,敬请期待今日14点的机会哦!');
}
}
需要比较:
二月七日凌晨到下午二点的时间不让用户领取奖品的比较,如下:
$nowDate=mktime(date('H'),date('i'),date('s'),date('m'),date('d'),date('Y'));
$day = date("d");
if($day == 7)
{
//第一天 2月7日
$forbidden_begin = mktime(0,0,0,2,7,2010);//开始时间
$forbidden_end = mktime(14,0,0,2,7,2010);//结束时间
if(($nowDate>=$forbidden_begin)&&($nowDate<=$forbidden_end))
{
return array('code'=>-1,'awardleft'=>0,'message'=>'兑换时间已过,敬请期待今日14点的机会哦!');
}
}