Bash脚本捕获input,运行命令并打印到文件

我正在做一个家庭作业,这是非常混乱的。 我不确定教授的例子是Perl还是bash,因为它没有头。 基本上,我只需要帮助解决这个问题:捕获input并输出。 这是作业:

  1. 在会话中,提供一个包含工作目录的命令提示符,例如$./logger/home/it244/it244/hw8$

  2. 接受用户的命令,执行它们,并在屏幕上显示输出。

  3. 在会话期间,创build一个临时文件“PID.cmd”(PID是进程ID),以下面的格式(index:command)存储命令历史logging:

    1: ls
    2: ls -l

  4. 如果脚本被CTRL + C (信号2)中止,则输出一条消息“ctrl + c中止”。

  5. 当您退出logging会话(通过“退出”或CTRL + C ),

    一个。 删除临时文件

    湾 打印会话中命令的总数和成功/失败命令的数量(根据退出状态)。

这是我的代码到目前为止(这不好,我不会尝试运行它):

  #!/bin/sh trap 'exit 1' 2 trap 'ctrl-c' 2 echo $(pwd) while true do read -p command echo "$command:" $command >> PID.cmd done 

目前,当我运行这个脚本,我得到

 command read: 10: arg count 

是什么原因造成的?

====== UPDATE =========

好吧,我做了一些进展不完全一样,它不喜欢我的bashtrap或增量指数

 #!/bin/sh index=0 trap bashtrap INT bashtrap(){ echo "CTRL+C aborting bash script" } echo "starting to log" while : do read -p "command:" inputline if [ $inputline="exit" ] then echo "Aborting with Exit" break else echo "$index: $inputline" > output $inputline 2>&1 | tee output (( index++ )) fi done 

由于发布的示例使用sh,我将在我的回复中使用它。 您需要将每个要求分解成特定的支持代码行。 例如,为了“提供包含工作目录的命令提示符”,您需要实际上将当前工作目录打印为读取命令的提示字符串,而不是通过设置$PS变量。 这导致read命令如下所示:

 read -p "`pwd -P`\$ " _command 

(我用私有变量的前导下划线 – 只是风格问题。)

类似地,要求在陷阱或正常出口上做几件事情,则暗示了一个函数应该被创建,然后可以被陷阱调用或者根据用户输入退出循环。 如果你想漂亮地打印出口信息,你也可以用echo命令包装它,看起来像这样:

 _cleanup() { rm -f $_LOG echo echo $0 ended with $_success successful commands and $_fail unsuccessful commands. echo exit 0 } 

因此,在分析了每个需求之后,您需要一些计数器和一些粘合代码(如while循环)来包装它们。结果可能如下所示:

 #/usr/bin/sh # Define a function to call on exit _cleanup() { # Remove the log file as per specification #5a rm -f $_LOG # Display success/fail counts as per specification #5b echo echo $0 ended with $_success successful commands and $_fail unsuccessful commands. echo exit 0 } # Where are we? Get absolute path of $0 _abs_path=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P ) # Set the log file name based on the path & PID # Keep this constant so the log file doesn't wander # around with the user if they enter a cd command _LOG=${_abs_path}/$$.cmd # Print ctrl+c msg per specification #4 # Then run the cleanup function trap "echo aborted by ctrl+c;_cleanup" 2 # Initialize counters _line=0 _fail=0 _success=0 while true do # Count lines to support required logging format per specification #3 ((_line++)) # Set prompt per specification #1 and read command read -p "`pwd -P`\$ " _command # Echo command to log file as per specification #3 echo "$_line: $_command" >>$_LOG # Arrange to exit on user input with value 'exit' as per specification #5 if [[ "$_command" == "exit" ]] then _cleanup fi # Execute whatever command was entered as per specification #2 eval $_command # Capture the success/fail counts to support specification #5b _status=$? if [ $_status -eq 0 ] then ((_success++)) else ((_fail++)) fi done 

这可以通过bash或perl或其他来实现。

一些提示,让你开始在bash中:

问题1 :命令提示符/记录器/ home / it244 / it244 / hw8
1)确保用户.bashrc安装文件中的提示格式:请参阅PS1数据以获取debian-like发行版。
2)cd到你的bash脚本中的那个目录。

问题2 :运行用户命令
1)获得用户输入

 read -p "command : " input_cmd 

2)运行用户命令到STDOUT

 bash -c "$input_cmd" 

3)跟踪用户输入命令退出代码

  echo $? 

如果一切正常,应该用“0”退出(你也可以在命令手册页找到退出代码)。

3)如果退出代码是OK,则跟踪命令PID

  echo $$ >> /tmp/pid_Ok 

但要注意的问题是保持用户命令输入,而不是像这里所示的PID本身。

4)出口陷阱
如果您误解了这个使用方法,请参阅man trap:您可以创建一个函数调用catched exit或CTRL / C信号。

5)增加你的while循环中的索引(在退出代码条件)

 index=0 while ... do ... ((index++)) done 

我想你已经足够开始你的家庭工作。