精华内容
下载资源
问答
  • 通过脚本实现操作的自动化

    千次阅读 2008-11-23 22:05:00
    了解 Shell 脚本如何实现所有个人或系统任务自动化。脚本可以执行监视、存档、更新、报告、上载和下载操作。实际上,任务无论大小,均可通过脚本来处理。下面是简介:如果您曾经在资深 UNIX® 用户工作时站在他...
      
    
    了解 Shell 脚本如何实现所有个人或系统任务自动化。脚本可以执行监视、存档、更新、报告、上载和下载操作。实际上,任务无论大小,均可通过脚本来处理。下面是简介:

    如果您曾经在资深 UNIX® 用户工作时站在他的背后注视屏幕,可能会对命令行上不断滚动的咒语般的奇怪内容感到相当迷惑。如果您阅读过对话 UNIX 系列中以前的文章(请参见参考资料),那么至少所输入的某些诗一般的神秘内容——如波形符 (~)、管道 (|)、变量和重定向(< 和 >)——看起来是熟悉的。您也许还会认出某些 UNIX 命令名称和组合,或者了解何时使用别名来作为某个命令组合的简写形式。

    尽管如此,还有其他命令组合可能是您无法理解的,因为资深的 UNIX 用户通常以 Shell 脚本 的形式收集一大堆小的、高度专门化的命令组合,以简化或自动化经常重复的任务。与输入或重新输入(可能)复杂的命令来完成某个繁琐任务不同,Shell 脚本可以自动化该工作。

    对话 UNIX 系列(请参见参考资料)的第 6 部分中,您将学习如何编写 Shell 脚本和更多命令行诀窍。

    核心就是一个词:“自动化”

    有些 Shell 脚本完全就是反复运行同样的命令,并处理同样的一组文件。例如,将您的整个主目录内容传播到三台远程计算机的 Z Shell 脚本可以像清单 1一样简单。


    清单 1. 跨多台计算机同步主目录的简单 Shell 脚本
     
    #! /bin/zsh
    
    for each machine (groucho chico harpo)
        rsync -e ssh --times --perms --recursive --delete $HOME $machine:
    end
    

    若要将清单 1用作 Shell 脚本,可以将上述内容保存到某个文件——例如 simpleprop.zsh——并运行 chmod +x simpleprop.zsh 以使该文件成为可执行文件。您可以通过输入 ./simpleprop.zsh 来运行该脚本。 

    如果您想查看 Z Shell 如何展开每个命令,可以将 -x 选项添加到脚本的 #!(# 号-感叹号对通常称为 shuh-bang)行的结尾,如下所示:

    #! /bin/zsh -x
    

    该脚本对 grouchochico 和 harpo 中的每一台计算机运行 rsync 命令,并将 $HOME 替换为您的主目录(例如,/home/joe),将 $machine 替换为计算机名称。

    清单 1 所示,变量和诸如循环等脚本控制结构使脚本更容易编写和维护。如果您想将第四台计算机(例如 zeppo)包括到计算机池中,只需将其添加到该列表。如果您必须更改 rsync 命令,比如说添加另一个选项,则只需编辑一个实例。与在传统编程中一样,您也应该努力避免在 Shell 脚本中进行剪切和粘贴。






    使用恰当的参数

    其他 Shell 脚本需要参数,或要处理的对象——文件、目录、计算机名称——的动态列表。例如,考虑清单 2,这是前一示例的变体,它允许您使用命令行来指定您想要与之同步的计算机。


    清单 2. 允许您指定要处理的计算机的清单 1 的变体
     
    #! /bin/zsh
    
    for each machine
        rsync -e ssh --times --perms --recursive --delete $HOME $machine:
    end
    

    假设您将清单 2保存在名为 synch.zsh 的文件中,您得按照 zsh synch.zsh moe larry curly 的形式调用该脚本,以将主目录复制到另外的计算机 larry 和 curly。

    foreach 行上缺少的列表并不是输入错误:如果您省略某个列表,则 foreach 结构将处理命令行上给出的参数列表。命令行参数也称为位置参数 (positional parameter),因为某个参数在命令行上的位置通常在语义上非常重要。

    例如,如果您 指定任何参数,则 清单 2 可以利用位置参数的存在性或非存在性来提供有帮助的用法信息。增强的脚本如清单 3 所示。


    清单 3. 许多脚本将在未提供参数时提供有帮助的消息
     
    #! /bin/zsh
    
    if [[ -z $1 || $1 == "--help" ]] 
    then
        echo "usage: $0 machine [machine ...]
    fi
    
    foreach machine
        rsync -e ssh --times --perms --recursive --delete $HOME $machine:
    end
    

    命令行上的每个空格分隔的字符串变成了位置参数,包括所调用的脚本的名称。因此,命令 synch.zsh 只有一个位置参数 $0synch.zsh --help 命令有两个位置参数:$0 和 $1,其中 $1 是字符串 --help

    所以,清单 3 表示“如果第一个位置参数为空(-z 操作符测试空字符串)或(由 || 表示)如果第一个参数等于‘—help’,则打印用法信息”。(如果您刚开始编写脚本,可以考虑在每个脚本中提供用法信息作为提示。它提醒其他人——甚至您自己,如果您忘了的话——如何使用该脚本。)

    短语 [[ -z $1 || $1 == "--help" ]] 是 if 语句的 条件,但您也可以将同样的条件子句用作命令,并将其与其他命令组合使用以控制通过脚本的流。请查看清单 4。它枚举您的 $PATH 中的所有可执行命令,并将条件与其他命令组合使用以执行适当的工作。


    清单 4. 列出 $PATH 中的命令
     
    #! /bin/zsh
    
    directories=(`echo $PATH | column -s ':' -t`) 
    
    for directory in $directories
    do
      [[ -d $directory ]] || continue
      
      pushd "$directory"
      
      for file in *
      do
          [[ -x $file && ! -d $file ]] || continue
          echo $file
      done
      
      popd
    done | sort | uniq
    

    此脚本中执行了相当多的操作,我们将它细分为以下几部分:

    1. 第一个实际脚本行——directories=(`echo $PATH | column -s ':' -t`)——创建指定目录的数组。您在 zsh 中通过将参数放在括号中来创建数据,例如 directories=(...)。在此例中,数组元素是通过在每个冒号(column -s ':')处分拆 $PATH 以产生空格分隔的目录列表(column 的 -t 参数)来生成的。 
    2. 对于列表中的每个目录,该脚本尝试枚举该目录中的可执行文件。步骤 3 至步骤 6 描述了该过程。 
    3. [[ -d $directory ]] || continue 行是所谓的 short-circuiting 命令的一个示例。short-circuiting 命令在其逻辑条件产生确定的结果时立即终止。 

      例如,[[ -d $directory ]] || continue 短语使用逻辑“或”(||)——它首先执行第一个命令,并且——当且仅当——第一个命令失败时才执行第二个命令。因此,如果 $directory 中的条目存在,并且是一个目录(-d 操作符),则测试成功,求值结束,并且 continue 命令(它跳过当前元素的处理)永远不会执行。

      然而,如果第一个测试失败,则会执行该逻辑的下一个条件或执行 continue。(continue 始终成功,因此它通常出现在 short-circuiting 命令的最后)。

      基于逻辑“与”(&&) 的 Short-circuiting 首先执行第一个命令,并且——当且仅当——第一个命令成功时才执行第二个命令。

    4. pushd 和对应的 popd 分别用于在处理前切换到新目录和在处理后切换到先前的目录。使用目录堆栈是一种理想的脚本技术,用于维持您在文件系统中的位置。 
    5. 内部的 for 循环枚举当前工作目录中的所有文件——通配符 *(星号)匹配所有条目——然后测试每个条目是否为文件。[[ -x $file && ! -d $file ]] || continue 行表示“如果 $file 存在并且是可执行文件而且不是目录,则处理它;否则执行 continue”。 
    6. 最后,如果前面的所有条件都满足,则使用 echo 来显示文件名。 
    7. 您弄明白该脚本的最后一行了吗?您可以将大多数控制结构的输出发送给另一个 UNIX 命令——毕竟,Shell 将该控制结构视为一个命令。因此,整个脚本的输出通过 sort、然后通过 uniq 进行管道传输,以产生在您的 $PATH 中找到的唯一命令的字母排序列表。 

    如果将清单 4 保存到一个名为 listcmds.zsh 的可执行文件,则输出可能类似如下:

    ./listcmds.zsh
    [
    a2p
    ab
    ac
    accept
    accton
    aclocal
    

    short-circuiting 命令在脚本中非常有用。它在单个命令中组合了条件和操作。而且由于每个 UNIX 命令都返回一个指示成功或失败的状态代码,因此,您可以使用任何命令作为“条件”——而不仅仅是使用测试操作符。根据约定,UNIX 返回零 (0) 表示成功,返回非零表示失败,其中非零值反映所发生的错误类型。

    例如,如果将 [[ -d $directory ]] || continue 行替换为 cd $directory || continue,则可以从清单 4 中消除 pushd 和 popd。如果 cd 命令成功,则它会返回 0,并且逻辑“或”的求值可以立即结束。然而,如果 cd 失败,则它会返回非零,并且会执行 continue






    不要删除。应存档!

    现代 UNIX Shell——bashkshzsh——提供了许多控制结构和操作以创建复杂的脚本。由于您可以调用所有 UNIX 命令来将数据从一种形式处理为另一种形式,Shell 脚本编程几乎与诸如 C 或 Perl 等完整语言中的编程一样丰富。

    您可以使用脚本来自动化几乎所有个人或系统任务。脚本可以监视、存档、更新、上载、下载和转换数据。一个脚本可以只有单行或包括无数个子系统。任务无论大小,均可通过脚本来处理。实际上,如果您查看 /etc/init.d 目录,会看到在每次启动计算机时运行服务的各种 Shell 脚本。如果您创建了一个非常有用的脚本,您甚至可以将它部署为系统范围的实用程序。只需将其放到用户的 $PATH 上的某个目录中。

    让我们创建一个实用程序,以练习您新发现的诀窍。脚本 myrm 将替换系统自己的 rm 实用程序。与彻底删除某个文件不同,myrm 把要删除的文件复制到某个存档,对其进行唯一命名以便您以后能够找到它,然后再删除原始文件。myrm 脚本有效但是非常简单,并且您还可以添加许多杂项功能。您还可以编写一个广泛的 unrm(撤销删除)脚本作为配套实用程序。(您可以搜索 Internet 来找到各种各样的实现。)

    myrm 脚本如清单 5 所示。


    清单 5. 用于在从文件系统中删除文件之前备份该文件的简单实用程序
     
    #! /bin/zsh
    
    backupdir=$HOME/.tomb
    systemrm=/bin/rm
    
    if [[ -z $1 || $1 == "--help" ]]
    then
      exec $systemrm
    fi
    
    if [[ ! -d $backupdir ]]
    then
      mkdir -m 0700 $backupdir || echo "$0: Cannot create $backupdir"; exit
    fi
    
    args$=$( getopt dfiPRrvw $* ) || exec $systemrm
    
    count=0
    flags = ""
    foreach argument in $args
    do
      case $argument in
        --) break;
            ;;
    
         *) flags="$flags $argument";
            (( count=$count + 1 ));
            ;;
      esac
    done
    shift $(( $count ))
    
    for file
    do
      [[ -e $file ]] || continue
      copyfile=$backupdir/$(basename $file).$(date "+%m.%d.%y.%H.%M.%S")
      /bin/cp -R $file $copyfile
    done
    
    exec $systemrm $=flags "$@"
    

    您应该发现该 Shell 脚本很容易理解,尽管其中存在一些之前尚未讨论过的新内容。让我们探讨一下那些新内容,然后查看整个脚本。

    1. 当 Shell 运行某个命令(如 cp 或 ls)时,它会为该命令产生一个新进程,然后在继续之前等待该(子)进程完成。exec 命令还启动另外一个命令,但是与产生新进程不同,exec 使用一个新命令来“替换”当前进程——即 Shell 进程——的任务。换句话说,exec 重用同一进程来启动一个新任务。在该脚本的上下文中,exec 立即“终止”该脚本并启动指定的任务。 
    2. UNIX 实用程序 getopt 扫描位置参数以获得您指定的命名参数。这里,dfiPRrvw 列表查找 -d-f-i-P-R-r-v 和 -w。如果出现别的选项,则 getopt 将会失败。否则,getopt 返回一个以特殊字符串 -- 结尾的选项字符串。 
    3. shift 命令从左到右删除位置参数。例如,如果命令行为 myrm, -r -f -P file1 file2 file3,则 shift 3 将分别删除 $0$1 和 $2,或 -r-f 和 -Pfile1file2 和 file3 将被重新编号为 $0$1 和 $2。 
    4. case 语句的工作方式与传统编程语言中的对应结构相似。它将其参数与列表中的每个模式比较;当找到匹配项时,则执行对应的代码。与在 Shell 中非常类似,* 匹配所有条目,并且可用作在未找到其他匹配项时的缺省操作。 
    5. 特殊符号 $@ 展开为所有(其余)的位置参数。 
    6. zsh 操作符 $= 在空白边界处拆分单词。当您有一个非常长的字符串,并且希望将该字符串拆分为各个参数时,$= 是非常有用的。例如,如果变量 x 包含字符串 '-r -f'——这是一个具有五个字符的单词——$=x 将变为两个单独的单词 -r 和 -f。 

    给出这些解释之后,您现在应该能够详细分析该脚本了。下面让我们逐块地研究一下该代码:

    • 第一个块设置整个脚本中使用的变量。 
    • 下一个块应该是非常熟悉的:它在未提供参数时打印用法信息。它为什么执行 (exec) 实际的 rm 实用程序呢?如果您将此脚本命名为“rm”并将其放在 $PATH 中靠前的位置,则它就可以充当 /bin/rm 的替代者。该脚本的错误选项也是 /bin/rm 的错误选项,因此该脚本允许 /bin/rm 提供用法信息。 
    • 下一个块在备份目录不存在时创建该目录。如果 mkdir 失败,则该脚本终止并显示适当的错误消息。 
    • 下一个块查找位置参数列表中的 dash 参数。如果 getopt 成功,则 $args 具有一个选项列表。如果 getopt 失败,例如在它无法识别某个选项的时候,则它会打印错误消息,并且该脚本将退出并显示用法信息。 
    • 随后的块捕获一个字符串中旨在提供给 rm 的所有选项。当遇到特殊 getopt 选项 -- 时,选项收集过程停止。shift 从参数列表中删除所有已处理的参数,保留待处理的文件和目录列表。 
    • 从以 for file 开头的块复制每个文件和目录,以便在您自己的存档目录中保存它们。每个文件的目录被逐字 (-R) 复制到存档目录,并附带当前日期和时间作为后缀,以确保该副本是唯一的,并且不会改写以前存档的具有相同名称的条目。 
    • 最后,使用传递给该脚本的相同命令行选项来删除文件和目录。 

    然而,如果您碰巧需要刚才删除(意外删除?)的文件或目录,您可以在存档中查找原始副本。






    向自动化进军

    您使用 UNIX 的时间越多,就越有可能创建脚本。脚本可以节省重新输入复杂的较长命令序列所需的时间和精力,并且还可以防止发生错误。Web 上充满了其他人已创建的用于许多目的的有用脚本。很快您也会发布自己的神奇脚本。

    展开全文
  • 为NGSOS智能操作系统设计编程语言

    千次阅读 2015-03-26 11:44:36
    最近空明魏在全栈工程师网站发起一场有关智能操作系统开发的倡议,诸多大牛热烈参与讨论,涉及编程语言如何选择,已成为其中一个焦点问题,多方争执不休,莫衷一是,本文就这个话题谈谈个人浅见。

    缘起

    最近空明魏在全栈工程师网站发起一场有关智能操作系统开发的倡议,诸多大牛热烈参与讨论,详情见这里。涉及编程语言如何选择,已成为其中一个焦点问题,多方争执不休,莫衷一是,本文就这个话题谈谈个人浅见。

     

    本文语境

    编程语言就是一种宗教,关乎信仰,一讨论起来就没完没了,最终也不会有结果。在我看来,适用的、能最优解决问题的都是好语言,谈语言必在特定语境下,把要解决的问题是什么,场景是什么,摆清楚,才可能有最佳结果。

    本文的语境就限定在空明魏所设想的“下一代智能操作系统”(NGSOS)上,假定为这个OS选择或新设计一套编程语言。关于NGSOS是什么,我摘录相关信息:

    首先,这个操作系统是传统通用操作系统的一个封装,而不是要替代现有的传统、通用操作系统,主要有两个特征:一个是统一的开发语言,另外一个是一次开发完成然后可运行在所有的现有操作系统之上。在 NGSOS 上,不同的设备或节点承担不同的角色,可以划分为客户端、服务器端和中继端。这些节点之间通过类似 DDP 的协议和 IM 协议同步和传输数据并进行各自的展现或处理。比如在智能手表上,主要负责收集数据然后发给智能手机,智能手机再发给云端服务器进行处理。这种情况下,智能手表是客户端,云端是服务器,智能手机是中继端。

    本文另一个语境设定是:如果我(Wayne Chan)为这个OS选配语言,该如何如何?每个人都有他的经验、层次、考虑问题出发点,别人我无从揣度,我只按自己的行业经验发表个人看法,有必要了解一下相关背景,点这个链接

     

    选择语言的依赖因素

    NGSOS长什么样尚未定论,这对语言选择有很大影响,关键问题未确定的,我先作假设,要不然,后文无从展开。

    其一:在什么设备上跑NGSOS?

    假定先在智能穿戴设备上用(这点存疑,穿戴设备在新体系中视作Driver,还是完备OS?姑且先假定后者),以后扩展到具有更强处理能力的设备,假定CPU至少是32位,内存至少128M,处理能力要超过当年Win95,如果处理能力太弱,编程语言选择肯定大不一样,也影响脚本解释器是否驻留。

    其二:如何与现有系统对接?

    脱离现系统(OS及OS之上基础服务框架),从零开始构造新系统不现实,也不必要,这么多开源的RTOS,从中选一个,这没疑义。问题是:OS之上的编程框架怎么定?选android,天然绑捆java,走MS路线的,C#最佳,如果不想脱离iOS,只能用C++ 与JS(因为ObjC、Swift被封闭系统圈住了)。语言与OS紧捆绑,涉及生态环境、商业形式、安全等因素,细论起来很复杂,我简化处理,就用C++与 JS,从iOS的限制倒推。C++ 在哪个OS都适用,能保证底层运行效率,JS在高层,可保证快速开发,也有广泛适用性(如果新操作系统不支持浏览器,就不该叫NGSOS,我假定NGSOS是必须支持WebApp开发的)。

    为什么不能绕过iOS?如果你承认iOS在智能设备市场处于领导地位,就不该想着绕开,它留点缝隙都是宝贵的资产(其间有深意,不展开),如果您认同选择C++ 与JS是NGSOS两个基本出发点,我们继续。

     

    构造边界

    每个OS都有边界,我们简单的将OS系统看成由两部分组成:含基础服务的操作系统,一套(或多套)编程体系。在前者构造边界,还是在后者构造边界?如果前者,你的主业只能卖一卖RTOS,NGSOS应该选后者,就像windows用.Net与C#,Android用java,iOS用objC,都用特色的编程体系强化它的生态特征。

    前面选择了C++ 与 JS,这才刚开始,如果仅依赖这两项,如何让你的系统具有商业价值?没有商业价值,或商业价值不高的系统,会很快消亡。所以,NGSOS上的编程语言还必须承担锁住(或强化)商业价值的责任。因为你不贩卖RTOS,重任只能由编程体系来承担,就像在iOS上开发APP,严格受限后,才维持Apple的优质生态。这里,我想强调的是:C++ 与JS是基点,在两者之上还得发展新语言。

    新兴生态系统还得解开“鸡生蛋,还是蛋生鸡”的死结,刚冒出来的OS应用少,应用少就没价值、没影响力,也就没有开发人员愿为它开发应用。看看微软近几年的表现就清楚了,如果找不出一条路径跳出这个闭环,只能一次次坐失良机,竞争对手一直快速迭代,高速前进,你很容易落下,而且越落越远。讲这个与编程语言有什么关系?关系大了,别人构造边界,你想办法打破边界呀,别人用编程系统筑墙,你就用编程系统翻墙呀!

     

    编程语言的发展趋势

    近些年来,与JavaScript相关的编程语言、框架或库很活跃,拜移动设备兴起、Html5技术发展等条件所赐,有关WebApp方面的创新层出不穷。融合WebApp与NativeApp,融合强类型与弱类型,俨然成为当今编程语言的发展趋势,苹果推Swift,微软搞TypeScript,Google推Dart,Facebook弄Reactive Native,Firefox搞Rust,都反映了这种趋势。

    JS仍是基于浏览器开发WebApp的不二选择,任何公司无论他多牛,当下都得接受这个现实,所以,MS只能用TypeScript编码翻译成JS,Google也只能用Dart开发,最后都译成JS脚本。之所以要用一种语言描述另一种语言,折腾一下,不外乎两大原因,一是JS存在不少固有缺陷(但还不致命),像某些语法易误用、不支持class、模块化特性欠佳、开发大工程困难、调试不方便等,二是JS太过动态,动态语言固有的某些缺陷要克服(主要是类型检查),加入一些静态语言特性。

    为NGSOS设计新语言,少不了要像Dart、TypeScript、CoffeeScript那样,先解决上面2大问题,但如果停留于这两点,市场上无非多一个 xxScript 语言而已,没有颠覆性,我们希望引入新东西,超越Swift、TypeScript不少,才能更有效吸引开发人员投身进来。不再卖关子,这个新语言就是CSE,因为作者认定这门语言是具有跨代意义,才这么多年坚持研发。CSE将脚本语言与编译语言合二为一,同时享受动态与静态语言的优势,结合NGSOS来说,它将带来如下几方面好处:

    1. 脚本化开发,在高抽象度层面编码,高效,编码过程清爽、愉快,我用Python开发做类比,大概要超过一些,因为智能提示、调测跟踪可以更优。
    2. 发布时代码译成C++,或为追求在线更新的效果,支持JIT,这两者保障代码运行效率达到C++水平,高出脚本(如Python或JS)百倍。
    3. 脚本在线JIT,实际可支持“热注入”机制,即:可运行代码任意迁移,免安装经物理传递后在远端运行。(这一点没什么特殊的,现有JS脚本也能做到,但若在NGSOS或Elasteos概念下会赋予新含义,如:网盘变网站,也能变服务热点)
    4. 避免Web开发过程碎片化,全程开发在一门语言框架内完成,避免分层切换调试,底层调一下(如java),切到上层又调一下(如JS),两者调试环境完全不同。(注:让CSE做到这一步路还有很长,但最终是可以做到的,要整合诸如Angular、react框架,让界面与逻辑良好分离后)
    5. 彻底混淆生成的JS代码,包括它依赖的各个底层库,一起混淆,此项保证发布的JS难被他人直接抄袭。TypeScript、Dark等不容易做到这一步,因为工程一体性难保证,翻译后JS常假定与工程外JS配合使用。
    6. 客户端开发与服务端开发合一。得益于CSE对Javascript的亲和性,CSE对NodeJS也是友好的,加之翻译转化的特性,CSE编程具有很宽挪腾余地,客户端开发与服务端开发可以统一起来。
    7. 在语言级别支持NoSQL DB(不考虑关系数据库)的操作表达,就像Python描述AWS的DynamoDB,比较简洁。CSE会更简洁,操作方式、数据表示等与语言内置类型无缝结合。
    8. 突破iOS AppStore发布条款限制,JS是iOS上唯一明文规定可以不经审核就能发布的(注:非明文规定,但审核能放行还有lua)。结合iOS6之后的JsBinding组件,在iOS上能实现的WebApp其实已经很强大。
      此举意义深远,用你的工具开发APP能跨越多个平台后,意味着,你可以到Apple的池塘去捞鱼,前面提到“别人筑墙,你再借编程语言翻墙”是这个意思。而且,此方案中,Apple处于劣势,因为同样程序,在别人平台能译成C++ 发布,在iOS只能慢腾腾跑脚本。(让Apple品尝一下封闭平台不得已的苦楚,嘿嘿)

    将脚本语言与编译语言融为一体,非常不易,如函数式、闭包、并发、这些要原生的融入语法语义,还有一点很关键,解释执行的实体如何高效的反映到C++ 数据对象上,没有精心设计你只能做到像Python扩展模块那样,处处与相对繁重的PyObject打交道(如“i += 1;”无法直接对数据结构的某偏址做累加)。这是前沿领域,要耗大量精力去积累,要不,MS、Google、Apple早有更牛逼的东西推出,这几家中,Swift走在前面,它的编程方式已非常接近脚本了,典型的,如采用类型推导定义变量(做法与CSE如出一辙),让编译语言用起来像脚本语言,再有Playground辅助,随时改一下代码,立即跑,在Playground即时看效果,表现脚本语言的应用效果。CSE比Swift做得更系统,更彻底些,Swift在Playground即时运行实际仍按编译方式进行,所以,只能把全部代码看作一个整体来跑,这导致Swift只能让片断代码受益于动态调测,CSE则在语句级别与函数级别实现“即时运行”,说白了,是真正的脚本语言在跑,调测中,能随时增加一个函数定义、类定义,随时写几条语句让它跑起来。

    从语言进化链上看,CSE更像从OO语言向脚本的进化,或者说,可视作Swift下一级进化物,而不是原型化脚本编程(如JS)的进化物,其间细节差异,包含了个人对语言发展趋势的判断。我讲一个佐证,最新消息,Google宣布Dart决定将集中精力在dart2js的使用模式上,Chrome浏览器将不再嵌入Dart VM。大体预示着:尝试发展一个新东西替代或越过JavaScript不是发展方向,JS有缺陷但不致命,况且还有ES6、ES7规范在一旁候着。所以,CSE选择这样道路是恰当的:独立自成主线,把JS当作中间过程,视JS语法为CSE一个子集,能翻译代码到JS。

    Swift专为Apple自家服务,遇到可能给iOS生态带来破坏的趋势,它就不会跟进,CSE没这个负担,我很乐意让CSE与JS合体,Swift做不到,不是技术做不了,而是不能自毁长城。这也是CSE可以发展壮大的一个机缘。

     

    双工开发模式

    前面讲了为NGSOS选择C++ 与JS两个基点,既是行业现状决定的,也是语言生态链上的自然选择,存在即合理。C++是OOP典范,JS是脚本语言中基于原型编程的典范,原型化比OO更为初始(也更基本),两者融合形态就是:C++ 更脚本化,JS更加面向对象化。

    CSE基于C++开发,CSE脚本可译为C++,所以,C++ 是CSE最基础、最底层的东西,你完全可以用C++ 在CSE基础类型库接口上做开发,对外接口按规格去写,由工具自动生成与脚本对接的binding,之后,可将它导入到CSE脚本解释器,由脚本调用它。

    双工开发模式是指:既可以用C++,也可以用CSE脚本做开发。极端情况下,比如设备能力非常受限,跑不了脚本解释器,这时只用C++ 做开发也是可以的。

     

    锁住商业价值

    基于前文描述,CSE若用作NGSOS的主编程言,它应该闭源,不是完全闭源,涉及语言内核的封闭起来,其底层与上层开放,底层主要类型库定义(如Number、String、Array等),必要的同步异步分发机制,及支持脚本解析运行的最基础环境(像线程、信号量等封装),这些必须开源,因为双工开发模式中的C++开发,要依赖这个底层库。

    上层开放是自然的事,核心语言只是小部分,一个体系需要大量的扩展库支撑起来,扩展库是开源的,而且会大幅度重用NodeJS现成资源。

    此策略对用户使用影响不大,拿VC类比,相当于VC Express你随便装,想要源码没门。编译工具闭源,但使用免费,这个体系其它部分全都开源。用局部闭源保证这个体系可持续发展。OS需要开源,不开源现状下已没发展空间。

     

    (本文太多假设,座而论道,夸夸其谈,见谅)

    展开全文
  • Python 语言编写的 Linux 系统监控工具 比如 inotify-sync(文件系统安全监控软件)、glances(资源监控工具)在实际工作中,Linux 系统管理员可以根据自己使用的服务器的具体情况编写一下简单实用的脚本实现对 ...
    

    目前 Linux 下有一些使用 Python 语言编写的 Linux 系统监控工具 比如 inotify-sync(文件系统安全监控软件)、glances(资源监控工具)在实际工作中,Linux 系统管理员可以根据自己使用的服务器的具体情况编写一下简单实用的脚本实现对 Linux 服务器的监控。 本文介绍一下使用 Python 脚本实现对 Linux 服务器 CPU 内存 网络的监控脚本的编写。

    Python 版本说明

    Python 是由 Guido van Rossum 开发的、可免费获得的、非常高级的解释型语言。其语法简单易懂,而其面向对象的语义功能强大(但又灵活)。Python 可以广泛使用并具有高度的可移植性。本文 Linux 服务器是 Ubuntu 12.10, Python 版本 是 2.7 。如果是 Python 3.0 版本的语法上有一定的出入。另外这里笔者所说的 Python 是 CPython,CPython 是用 C 语言实现的 Python 解释器,也是官方的并且是最广泛使用的Python 解释器。除了 CPython 以外,还有用 Java 实现的 Jython 和用.NET 实现的 IronPython,使 Python方便地和 Java 程序、.NET 程序集成。另外还有一些实验性的 Python 解释器比如 PyPy。CPython 是使用字节码的解释器,任何程序源代码在执行之前先要编译成字节码。它还有和几种其它语言(包括 C 语言)交互的外部函数接口。

    工作原理:基于/proc 文件系统

    Linux 系统为管理员提供了非常好的方法,使其可以在系统运行时更改内核,而不需要重新引导内核系统,这是通过/proc 虚拟文件系统实现的。/proc 文件虚拟系统是一种内核和内核模块用来向进程(process)发送信息的机制(所以叫做“/proc”),这个伪文件系统允许与内核内部数据结构交互,获取有关进程的有用信息,在运行中(on the fly)改变设置(通过改变内核参数)。与其他文件系统不同,/proc 存在于内存而不是硬盘中。proc 文件系统提供的信息如下:

    • 进程信息:系统中的任何一个进程,在 proc 的子目录中都有一个同名的进程 ID,可以找到 cmdline、mem、root、stat、statm,以及 status。某些信息只有超级用户可见,例如进程根目录。每一个单独含有现有进程信息的进程有一些可用的专门链接,系统中的任何一个进程都有一个单独的自链接指向进程信息,其用处就是从进程中获取命令行信息。
    • 系统信息:如果需要了解整个系统信息中也可以从/proc/stat 中获得,其中包括 CPU 占用情况、磁盘空间、内存对换、中断等。
    • CPU 信息:利用/proc/CPUinfo 文件可以获得中央处理器的当前准确信息。
    • 负载信息:/proc/loadavg 文件包含系统负载信息。
    • 系统内存信息:/proc/meminfo 文件包含系统内存的详细信息,其中显示物理内存的数量、可用交换空间的数量,以及空闲内存的数量等。

    表 1 是 /proc 目录中的主要文件的说明:

    表 1 /proc 目录中的主要文件的说明
    文件或目录名称描 述
    apm高级电源管理信息
    cmdline这个文件给出了内核启动的命令行
    CPUinfo中央处理器信息
    devices可以用到的设备(块设备/字符设备)
    dma显示当前使用的 DMA 通道
    filesystems核心配置的文件系统
    ioports当前使用的 I/O 端口
    interrupts这个文件的每一行都有一个保留的中断
    kcore系统物理内存映像
    kmsg核心输出的消息,被送到日志文件
    mdstat这个文件包含了由 md 设备驱动程序控制的 RAID 设备信息
    loadavg系统平均负载均衡
    meminfo存储器使用信息,包括物理内存和交换内存
    modules这个文件给出可加载内核模块的信息。lsmod 程序用这些信息显示有关模块的名称,大小,使用数目方面的信息
    net网络协议状态信息
    partitions系统识别的分区表
    pcipci 设备信息
    scsiscsi 设备信息
    self到查看/proc 程序进程目录的符号连接
    stat这个文件包含的信息有 CPU 利用率,磁盘,内存页,内存对换,全部中断,接触开关以及赏赐自举时间
    swaps显示的是交换分区的使用情况
    uptime这个文件给出自从上次系统自举以来的秒数,以及其中有多少秒处于空闲
    version这个文件只有一行内容,说明正在运行的内核版本。可以用标准的编程方法进行分析获得所需的系统信息

    下面本文的几个例子都是使用 Python 脚本读取/proc 目录中的主要文件来实现实现对 Linux 服务器的监控的 。

    使用 Python 脚本实现对 Linux 服务器的监控

    对于 CPU(中央处理器)监测

    脚本 1 名称 CPU1.py,作用获取 CPU 的信息。

    清单 1.获取 CPU 的信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #!/usr/bin/env Python
    from __future__ import print_function
    from collections import OrderedDict
    import pprint
     
    def CPUinfo():
         ''' Return the information in /proc/CPUinfo
         as a dictionary in the following format:
         CPU_info['proc0']={...}
         CPU_info['proc1']={...}
         '''
         CPUinfo = OrderedDict()
         procinfo = OrderedDict()
     
         nprocs = 0
         with open ( '/proc/CPUinfo' ) as f:
             for line in f:
                 if not line.strip():
                     # end of one processor
                     CPUinfo[ 'proc%s' % nprocs] = procinfo
                     nprocs = nprocs + 1
                     # Reset
                     procinfo = OrderedDict()
                 else :
                     if len (line.split( ':' )) = = 2 :
                         procinfo[line.split( ':' )[ 0 ].strip()] = line.split( ':' )[ 1 ].strip()
                     else :
                         procinfo[line.split( ':' )[ 0 ].strip()] = ''
     
         return CPUinfo
     
    if __name__ = = '__main__' :
         CPUinfo = CPUinfo()
         for processor in CPUinfo.keys():
             print (CPUinfo[processor][ 'model name' ])

    简单说明一下清单 1,读取/proc/CPUinfo 中的信息,返回 list,每核心一个 dict。其中 list 是一个使用方括号括起来的有序元素集合。List 可以作为以 0 下标开始的数组。Dict 是 Python 的内置数据类型之一, 它定义了键和值之间一对一的关系。OrderedDict 是一个字典子类,可以记住其内容增加的顺序。常规 dict 并不跟踪插入顺序,迭代处理时会根据键在散列表中存储的顺序来生成值。在 OrderedDict 中则相反,它会记住元素插入的顺序,并在创建迭代器时使用这个顺序。

    可以使用 Python 命令运行脚本 CPU1.py 结果见图 1

    1
    2
    # Python CPU1.py
    Intel(R) Celeron(R) CPU E3200  @ 2.40GHz
    图 1.运行清单 1

    ypjbsxdlfwqdjk01

    也可以使用 chmod 命令添加权限收直接运行 CPU1.py

    1
    2
    #chmod +x CPU1.py
    # ./CPU1.py

    对于系统负载监测

    脚本 2 名称 CPU2.py,作用获取系统的负载信息

    清单 2 获取系统的负载信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/usr/bin/env Python  
    import os
    def load_stat():
         loadavg = {}
         f = open ( "/proc/loadavg" )
         con = f.read().split()
         f.close()
         loadavg[ 'lavg_1' ] = con[ 0 ]
         loadavg[ 'lavg_5' ] = con[ 1 ]
         loadavg[ 'lavg_15' ] = con[ 2 ]
         loadavg[ 'nr' ] = con[ 3 ]
         loadavg[ 'last_pid' ] = con[ 4 ]
         return loadavg
    print "loadavg" ,load_stat()[ 'lavg_15' ]

    简单说明一下清单 2:清单 2 读取/proc/loadavg 中的信息,import os :Python 中 import 用于导入不同的模块,包括系统提供和自定义的模块。其基本形式为:import 模块名 [as 别名],如果只需要导入模块中的部分或全部内容可以用形式:from 模块名 import *来导入相应的模块。OS 模块 os 模块提供了一个统一的操作系统接口函数,os 模块能在不同操作系统平台如 nt,posix 中的特定函数间自动切换,从而实现跨平台操作。

    可以使用 Python 命令运行脚本 CPU1.py 结果见图 2 # Python CPU2.py

    图 2.运行清单 2

    ypjbsxdlfwqdjk02

    对于内存信息的获取

    脚本 3 名称 mem.py,作用是获取内存使用情况信息

    清单 3 获取内存使用情况
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #!/usr/bin/env Python
     
    from __future__ import print_function
    from collections import OrderedDict
     
    def meminfo():
         '' ' Return the information in /proc/meminfo
         as a dictionary '' '
         meminfo=OrderedDict()
     
         with open( '/proc/meminfo' ) as f:
             for line in f:
                 meminfo[line.split( ':' )[ 0 ]] = line.split( ':' )[ 1 ].strip()
         return meminfo
     
    if __name__== '__main__' :
         #print(meminfo())
     
         meminfo = meminfo()
         print( 'Total memory: {0}' .format(meminfo[ 'MemTotal' ]))
         print( 'Free memory: {0}' .format(meminfo[ 'MemFree' ]))

    简单说明一下清单 3:清单 3 读取 proc/meminfo 中的信息,Python 字符串的 split 方法是用的频率还是比较多的。比如我们需要存储一个很长的数据,并且按照有结构的方法存储,方便以后取数据进行处理。当然可以用 json 的形式。但是也可以把数据存储到一个字段里面,然后有某种标示符来分割。 Python 中的 strip 用于去除字符串的首位字符,最后清单 3 打印出内存总数和空闲数。

    可以使用 Python 命令运行脚本 mem.py 结果见图 3。 # Python mem.py

    图 3.运行清单 3

    ypjbsxdlfwqdjk03

    对于网络接口的监测

    脚本 4 名称是 net.py,作用获取网络接口的使用情况。

    清单 4 net.py 获取网络接口的输入和输出
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #!/usr/bin/env Python
    import time
    import sys
     
    if len (sys.argv) > 1 :
         INTERFACE = sys.argv[ 1 ]
    else :
         INTERFACE = 'eth0'
    STATS = []
    print 'Interface:' ,INTERFACE
     
    def rx():
         ifstat = open ( '/proc/net/dev' ).readlines()
         for interface in  ifstat:
             if INTERFACE in interface:
                 stat = float (interface.split()[ 1 ])
                 STATS[ 0 :] = [stat]
     
    def tx():
         ifstat = open ( '/proc/net/dev' ).readlines()
         for interface in  ifstat:
             if INTERFACE in interface:
                 stat = float (interface.split()[ 9 ])
                 STATS[ 1 :] = [stat]
     
    print   'In         Out'
    rx()
    tx()
     
    while   True :
         time.sleep( 1 )
         rxstat_o = list (STATS)
         rx()
         tx()
         RX = float (STATS[ 0 ])
         RX_O = rxstat_o[ 0 ]
         TX = float (STATS[ 1 ])
         TX_O = rxstat_o[ 1 ]
         RX_RATE = round ((RX - RX_O) / 1024 / 1024 , 3 )
         TX_RATE = round ((TX - TX_O) / 1024 / 1024 , 3 )
         print RX_RATE , 'MB      ' ,TX_RATE , 'MB'

    简单说明一下清单 4:清单 4 读取/proc/net/dev 中的信息,Python 中文件操作可以通过 open 函数,这的确很像 C 语言中的 fopen。通过 open 函数获取一个 file object,然后调用 read(),write()等方法对文件进行读写操作。另外 Python 将文本文件的内容读入可以操作的字符串变量非常容易。文件对象提供了三个“读”方法: read()、readline() 和 readlines()。每种方法可以接受一个变量以限制每次读取的数据量,但它们通常不使用变量。 .read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。然而 .read() 生成文件内容最直接的字符串表示,但对于连续的面向行的处理,它却是不必要的,并且如果文件大于可用内存,则不可能实现这种处理。.readline() 和 .readlines() 之间的差异是后者一次读取整个文件,象 .read() 一样。.readlines() 自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for … in … 结构进行处理。另一方面,.readline() 每次只读取一行,通常比 .readlines() 慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用 .readline()。最后清单 4 打印出网络接口的输入和输出情况。

    可以使用 Python 命令运行脚本 net.py 结果见图 4 #Python net.py

    图 4.运行清单 4

    ypjbsxdlfwqdjk04

    监控 Apache 服务器进程的 Python 脚本

    Apache 服务器进程可能会因为系统各种原因而出现异常退出,导致 Web 服务暂停。所以笔者写一个 Python 脚本文件:

    清单 5 crtrl.py 监控 Apache 服务器进程的 Python 脚本
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/env Python
    import os, sys, time
     
    while True :
    time.sleep( 4 )
    try :
    ret = os.popen( 'ps -C apache -o pid,cmd' ).readlines()
    if len (ret) < 2 :
    print "apache 进程异常退出, 4 秒后重新启动"
    time.sleep( 3 )
    os.system( "service apache2 restart" )
    except :
    print "Error" , sys.exc_info()[ 1 ]

    设置文件权限为执行属性(使用命令 chmod +x crtrl.py),然后加入到/etc/rc.local 即可,一旦 Apache 服务器进程异常退出,该脚本自动检查并且重启。 简单说明一下清单 5 这个脚本不是基于/proc 伪文件系统的,是基于 Python 自己提供的一些模块来实现的 。这里使用的是 Python 的内嵌 time 模板,time 模块提供各种操作时间的函数。

    总结

    在实际工作中,Linux 系统管理员可以根据自己使用的服务器的具体情况编写一下简单实用的脚本实现对 Linux 服务器的监控。本文介绍一下使用 Python 脚本实现对 Linux 服务器 CPU 、系统负载、内存和 网络使用情况的监控脚本的编写方法。

    展开全文
  • 简介最近专注于捣腾mac系统,发现了系统语音朗读的功能,于是萌生了从一些天气服务的API获得并解析天气,在本地调用语音朗读指令,使得电脑上的“天气预报”也实现播报功能。代码我已经上传到本人的GitHub上去了,...

    简介

    最近专注于捣腾mac系统,发现了系统语音朗读的功能,于是萌生了从一些天气服务的API获得并解析天气,在本地调用语音朗读指令,使得电脑上的“天气预报”也实现播报功能。

    代码我已经上传到本人的GitHub上去了,需要的可以任意取用。

    代码实现不是很麻烦,看得懂的人看看就晓得了。如果看不懂,也不需要纠结(看得懂我那蹩脚的英文说明和注释也足够了)。

    代码中解析的天气服务,来自雅虎提供的天气API:http://xml.weather.yahoo.com/forecastrss?w={0}&u={1}

    其中,参数{0}表示城市代码,也是唯一你可能需要改动的地方,我使用的是南京。你所在的城市代码,可以在这里查找到:http://sigizmund.info/woeidinfo/

    参数{1}表示使用的温度单位,不玩非主流,传入“c”表示使用摄氏度,另一值为“F”

    需要的支持库:FeedParser

    因为Yahoo!提供的这个API返回的格式是标准的RSS 2.0格式,而Python也正好提供了一个解析RSS的库,名为:FeedParser;因此,那段程序脚本需要该库的支持。

    关于如何安装该RSS解析库?

    如果你已经安装了Pip,那么就是一句话的事情:

    pip install feedparser

    如果,你没有安装过pip,我这里就不说了,教程网上是可以找到的(建议先安装pip,然后安装该库)

    开启系统语音朗读功能

    既然需要语音播报,当然需要开启系统语音相关的功能,这里因为需要用中文播报,需要开启中文朗读,Apple的国际化做得还不错,提供了中文语音库,不过需要下载。

    首先,打开系统设置中的如下设置项:


    进入后切换至“Text to speech”(中文的系统应该是文本至语音吧):


    点开“System Voice”后的下来菜单,选择不同语言的语音库,默认的是英文语音,选择自定义查找“Chinese”:


    可以看到只中文相关的就提供了三种语音库:中国大陆简体、广东话、中华台湾的台湾话(赶紧收复那该死的TW吧!):


    注:虽然提供了,但没有内置到你目前的操作系统,所以当你选择的时候,会提示你先下载(文件还不小,所以按需下载,我这里打上勾代表我已经下载了中文库了)

    下载完,选择中文即可,点击Play是可以试听的!

    好了,以上就已经使得默认的语音库为中文语音库了。如何测试,它会读中文?你可以在应用程序的实用工具里找到“终端”(英文系统叫Terminal)。打开它,然后输入:

    say 祝你:身体健康

    系统就会自动朗读:祝你:身体健康

    为系统设置定时唤醒和定时开机的系统计划

    这个同样不难,进入系统设置,选择节能灯的菜单:


    进入点击:


    进入,即可设置定时计划:


    系统定时开机设置完毕!

    下面,还是回到我上篇文章中如何使得一个脚本程序开机自启。需要的文件,我已经在代码库里提供了。

    代码注解

    代码中,我自己设置了,假如过了九点机子才被开机,那么将取消自动播报天气预报:

    #before 08:59:59, the weather voice reportor will start 
        if time.localtime(time.time())[3] <= 8:
            parserRSSFeed(WEATHER_SERVICE_URL)

    上面提到的如何设置系统定时开机,不是必须动作,这只不过可以使得这个程序看起来更为“智能”一点。

    因为,say命令遇到一些特殊字符,会使得朗读命令失效,所以,我简单得列举了几个我碰到过的失败的例子的正则表达式,如果文字中包含这些,则将其替换:

    #handle some "special char" which will stop the "speak order"
    #such as -、(、).....
    PRE_PROCESSING_EXPRESSION=\
    (
        ('[-]'          ,   '负'),
        ('[\(]'         ,   '左括号'),
        ('[\)]'         ,   '右括号')
        #......
        #TODO:append more
    )

    def processSpeakingTxt(txtStr):
        global PRE_PROCESSING_EXPRESSION
        for (reg_Expression, replaceingStr) in PRE_PROCESSING_EXPRESSION:
            if re.search(reg_Expression, txtStr) is not None:
                txtStr = re.sub(reg_Expression, replaceingStr, txtStr)
        return txtStr


    另外如果你不想改.sh和.plist文件,你还需要在/usr/local下新建一个名为:customizeService的文件夹,然后把.py和.sh的两个文件放到其下。.plist文件如何放置,还是看我上一篇文章。

    最好,还要提醒一下:成功执行的前提是——系统开机时,电脑已连接互联网(否则你如果想听见语音播报,只能在之后,自己手动执行了)


    展开全文
  • 随着数据量的激增, 在linux系统环境下执行数据分析模型时由于运行时间太长,会出现 Connection closed by foreign host, 往往程序运行未结束时出现这样的错误,让人头疼,本文来总结下在linux系统下在后台执行R...
  • 来源:http://www.ibm.com/developerworks/cn/linux/1312_caojh_pythonlinux/ 曹 江华, 系统管理员, 中科思密达有限公司目前 Linux 下有一些使用 Python 语言编写的 Linux 系统监控工具 比如 inotify-sync(文件...
  • 这可能最全的操作系统面试题

    千次阅读 多人点赞 2021-04-13 09:30:37
    Linux 系统下的应用程序不能直接在 Windows 下运行操作系统结构单体系统分层系统微内核客户-服务器模式为什么称为陷入内核什么是用户态和内核态用户态和内核态是如何切换的?什么是内核什么是实时系统Linux 操作系统...
  • Cocos2d-x 脚本语言Lua的使用

    万次阅读 2014-06-22 14:10:50
    Cocos2d-x 脚本语言Lua的使用前面几篇博客已经把Lua的相关基础知识介绍了,本篇博客就来介绍一下,如何在Cocos2d-x项目中使用Lua这门脚本语言进行开发。由于笔者使用的时Mac系统,所以演示给大家的时在XCode当中运行...
  • Linux中编写Shell脚本

    万次阅读 多人点赞 2018-10-08 11:22:35
    Shell脚本的执行 Shell脚本编写规范 Shell 中的变量 变量的算术运算 双小括号 (()) 数值运算命令的用法 let 运算命令的用法 expr 命令的用法 br 命令的用法 $[]符号的运算示例 Shell脚本的条件测试 几种...
  • 考研操作系统笔记

    千次阅读 多人点赞 2019-01-05 19:40:08
    第一章: 操作系统引论 操作系统的定义 操作系统的功能(4个管理,3个接口) 处理器管理 存储器管理 文件管理 设备管理 用户接口 命令接口{ 联机命令接口, 脱机接口(批处理命令接口)(*.bat, shell脚本) } ...
  • Windows系统Shell脚本

    千次阅读 2019-04-29 09:06:50
    eg: echo %date% %time% --- // 当前目录 cd eg: echo %cd% 其他系统变量 # 只可以用在批处理文件中,表示所在的批处理文件的目录 %~dp0 # 执行脚本文件名 %~n0 # 执行脚本文件名(加后缀) %~nx0 命令 查看命令列表...
  • 用Python脚本实现对Linux服务器的监控

    千次阅读 2014-09-04 11:16:59
    一、前言 二、概述 三、Python 版本说明 ...四、/proc 文件系统 ...九、监控apache服务器进程的Python脚本 十、总结 注,测试环境 CentOS 6.4 x86_64,Python 版本 Python 2.6.6。 一、前言
  • python脚本编写

    万次阅读 多人点赞 2019-03-29 22:37:20
    什么是脚本 Python 是一种“脚本语言”。...而计算机中的脚本,决定了:计算机中的操作系统和各种软件工具,要做哪些事情,以及具体怎么做。 脚本 vs 程序 你可能想要了解脚本与一般程序的区别...
  • 切换用户,每次输入密码,比较麻烦,可以使用脚本交互式登录实现,每次只要输入./su_ 并tab,执行此脚本,即可切换至root用户,比较简单。如下: hao@hao-ubuntu:~$ cat su_root.sh #!/usr/bin/expect set timeout 3...
  • Linux操作系统

    千次阅读 2020-06-28 13:16:42
    文章目录Linux 操作系统Linux操作系统简介Linux 操作系统结构文件系统结构主要目录功能绝对路径和相对路径环境变量编译器使用vi使用Vi常用命令shell命令基础命令压缩管理软件管理用户管理ssh服务Linux下的SSH服务ssh...
  • 据大家所知,有没有这样一种脚本语言:专门用于编辑文本信息?我现在是比较习惯 Emacs 的快捷键,而且最近使用的键盘按方向键不太方便,所以很希望所使用的软件都能用 Emacs 的快捷键来操作。一开始,我使用 ...
  • 操作系统总结

    万次阅读 2016-08-22 21:08:48
    from:... ... ...第一章 操作系统引论 ...系统的目标:有效性(提高资源利用率和系统吞吐量)、方便性、可扩充性、开放性。有效性和方便性是操作系统最重要两
  • shell脚本的一些基本操作

    千次阅读 2016-11-27 10:09:38
    shell脚本不过是一些文件,我们将一系列需要执行的命令写入其中,然后通过shell来执行这些命令。 shell脚本的执行方式 1. sh script.sh # 脚本在当前目录下 2. ./script.sh #在当前目录下直接执行,不过需要赋予...
  • Ubuntu系统Shell脚本

    千次阅读 2019-01-28 11:26:50
    命令 常用 # 查看所有环境变量 - 打印环境变量 env echo $PATH ...# 打印系统信息 grep -v "U" 反向不匹配 uname -a # 账号和密码 - 切换账号 - 设置账号密码 su root su - sudo passwd root # 打...
  • Unity 脚本入门教程

    万次阅读 多人点赞 2017-09-05 14:02:17
    Unity 的许多功能都要通过它的富脚本语言 C# 来体现。你可以用它来处理用户输入,操作场景中的对象,碰撞检测,自动生成新的 GameObject 和在场景中发射定向光以处理游戏逻辑。听起来很可怕,但 Unity 提供了有良好...
  • 操作系统常见面试题

    万次阅读 2018-04-23 20:39:07
    常见面试题:1、进程是并发过程中程序的执行过程2、进程的特征:结构特征动态性并发性独立性异步性3、临界区指在每个进程中访问临界资源的那段代码4,现在操作系统中申请资源的基本单位是进程,在CPU得到执行的基本...
  • 简说window操作系统

    千次阅读 2018-04-09 21:34:45
    1985年11月20日,微软发布了Windows。最初的Windows仅仅是为MS-DOS系统提供图形界面... Microsoft Windows(在中文地区常以其英文名称呼,有时也被称作“微软窗口操作系统”或“微软视窗操作系统”)是微软公司推出...
  • Ubuntu系统中sh脚本编写

    万次阅读 2018-10-22 11:20:31
    我们在使用Ubuntu系统开发的过程中,经常会遇到一些重复的操作,想copy, push等等。这个时候我们就可以自己编写一个sh脚本,使用sh脚本操作这些重复的动作。 1.在编写sh脚本前了解一下基本语法 1.1 if语句 #!/bin/sh...
  • 写一个简单的操作系统

    万次阅读 多人点赞 2017-03-20 15:30:52
    如果一定要找出OS最重要的核心,那就是调度器,调度器本身即可以看作一个简单的操作系统,允许以周期性或单次方式来调用任务。从底层的角度看,调度器可以看作是一个由许多不同任务共享的定时器中断服务程序,因此,...
  • TI 实时操作系统SYS/BIOS使用总结

    万次阅读 多人点赞 2016-07-17 22:04:36
    SYS/BIOS 是一个可扩展的实时的操作系统。具有非常快速的响应时间(在中断和任务切换时达到较短的延迟),响应时间的确定性,强壮的抢占系统,优化的内存分配和堆栈管理(尽量少的消耗和碎片)。能够实现系统的模块...
  • Modelsim中.do脚本语言基本介绍

    千次阅读 2018-09-04 19:27:04
    该命令的作用是在当前目录下建立一个work目录,请注意不要直接在windows中新建一个work的文件夹,因为用操作系统建立的work文件夹并没有ModelSim SE自动生成的_info文件。) vmap work work (对应仿真步骤①:该...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 73,896
精华内容 29,558
关键字:

脚本实现切换操作系统语言