shell 函数 入参说明

本文介绍Shell脚本中如何处理传入的参数,包括使用$#获取参数个数,$0获取脚本名称,$1等获取指定位置的参数,$*与$@的区别及应用场景,并通过两个实例演示如何在函数中正确使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 入参个数: $#

2. 入参:  $0  脚本名    $1第一个参数

3.  $@ 和 $*: 

      "$@"  "$*"  都是所有入参

      $@  将入参变成一个数组     $*将入参变成一个字符串

4. 数组作为入参: fucn2  ${arr[*]} ,函数内部获取入参数组:   arr=` echo "$@" `


demo :



function test1 {
    if [ "$#" -ne 3 ]
    then
        echo "3 params..."
    fi
    
    echo "travel \$* : "
    for item in "$*"
    do
        echo $item
    done


    echo "travel \$@ : "
    for item in "$@"
    do
        echo $item
    done


}


function test2 {
    newArr=($(echo "$@"))
    local sum=0
    for value in ${newArr[*]}
    do
        sum=$[$sum+$value]
    done
    echo "test2 sum : "$sum
}


test1  a b c


myarr=(1 2 3 4)
test2 ${myarr[*]}


结果输出:

travel $* : 
a b c
travel $@ : 
a
b
c
test2 sum : 10

<think>好的,用户的问题是关于如何在Windows上用C语言实现一个不带数的shell程序。我需要先理解shell的基本工作原理。根据引用[1]中的信息,shell是一个命令解释器,负责用户与操作系统之间的交互。所以,核心功能应该是读取用户输的命令,然后执行这些命令。 接下来,用户提到的是无数版本,也就是说不需要处理像-l或-a这样的数。但需要处理基本的命令,比如启动其他程序。在Windows环境下,创建进程的API是关键。我记得Windows提供了CreateProcess函数,这可能需要在代码中使用。引用[4]中提到了一些关于字符串转换的宏,比如T2CW和T2CA,这可能涉及到处理Unicode和ANSI字符串的问题,不过用户的问题可能不需要复杂的数处理,所以暂时可以简化这部分。 然后,我需要考虑如何读取用户输。C语言中可以使用fgets函数从标准输读取命令。然后解析输,分割命令和数。例如,用户输"notepad",就需要执行notepad.exe。这里可能需要将命令分成可执行文件名,并传递给CreateProcess。 另外,引用[2]提到用C语言编写简单shell的例子,虽然主要是针对Linux,但结构上可能类似。例如,循环读取输,解析命令,执行。需要将这种结构转换到Windows API上。 还需要注意Windows和Linux在路径和可执行文件扩展名上的不同。比如,在Windows中,可能需要自动添加.exe扩展名,或者在PATH环境变量中查找可执行文件。但用户的问题是无数版本,可能不需要处理复杂的路径,直接使用系统命令或者当前目录下的程序。 可能遇到的问题包括处理空格分隔的数,但用户要求的是无数版本,所以可能每个命令都是单一的名称,没有数。比如,输"dir"就执行dir命令,但dir其实是内部命令,可能需要特殊处理。不过,对于外部命令,比如notepad,可以直接启动。 另外,需要处理命令的执行结果,比如等待进程结束。在Windows中,可以使用WaitForSingleObject来等待子进程结束。 综上所述,步骤大致如下: 1. 循环读取用户输的命令。 2. 解析命令,去除换行符等。 3. 使用CreateProcess启动该命令对应的进程。 4. 等待进程结束,继续循环。 可能还需要处理错误情况,比如命令不存在时提示错误信息。此外,需要考虑如何退出shell,比如当用户输"exit"时退出循环。 在代码实现上,可能需要包含Windows头文件,比如windows.h,并使用CreateProcess的数。例如,将命令字符串转换为LPWSTR,因为Windows API通常使用Unicode。但用户如果使用ANSI版本,可能需要调整。不过引用[4]提到了T2CW和T2CA宏,这可能涉及到使用ATL库,但用户可能希望一个简单的实现,所以可能直接使用ANSI版本的函数,或者进行必要的字符串转换。 测试时,可能需要编译为Windows可执行文件,使用Visual Studio或者MinGW等工具。用户可能还需要了解如何编译C程序为Windows应用。 最后,根据用户提供的引用,特别是引用[2]中的例子,虽然针对Linux,但结构可借鉴。需要将Linux的系统调用替换为Windows对应的API,比如用CreateProcess代替fork和exec。</think>要实现一个不带数的简易Shell程序,可以按照以下步骤操作: ### 一、实现原理 Windows Shell程序需要实现命令输、解析和执行三个核心模块。关键点在于使用Windows API的$CreateProcess$函数创建子进程[^4],并等待命令执行完成。 ### 二、代码实现 ```c #include <windows.h> #include <stdio.h> #include <string.h> #define MAX_CMD_LENGTH 1024 void execute_command(char* cmd) { STARTUPINFOA si = { sizeof(si) }; PROCESS_INFORMATION pi; // 设置命令路径(需要完整路径或系统环境变量中的可执行文件) char syscmd[MAX_CMD_LENGTH + 5]; snprintf(syscmd, sizeof(syscmd), "C:\\Windows\\System32\\%s.exe", cmd); if (CreateProcessA( NULL, // 可执行文件路径(已在syscmd中) syscmd, // 命令行数 NULL, // 进程安全属性 NULL, // 线程安全属性 FALSE, // 不继承句柄 0, // 无标志 NULL, // 使用父进程环境变量 NULL, // 使用父进程目录 &si, &pi) ) { WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } else { printf("命令无法执行:%s\n", cmd); } } int main() { char cmd[MAX_CMD_LENGTH]; while(1) { printf("mysh> "); fgets(cmd, MAX_CMD_LENGTH, stdin); // 移除换行符 cmd[strcspn(cmd, "\r\n")] = 0; if (strcmp(cmd, "exit") == 0) break; if (strlen(cmd) > 0) { execute_command(cmd); } } return 0; } ``` ### 三、关键点说明 1. **命令执行**:使用$CreateProcessA$创建进程,数需要完整路径或系统环境变量中的可执行文件 2. **路径处理**:默认查找$C:\\Windows\\System32$目录下的程序(可扩展为搜索PATH变量) 3. **字符串处理**:使用$strcspn$清除输中的换行符,避免命令解析错误 4. **进程等待**:$WaitForSingleObject$确保子进程执行完毕后再接受新命令 ### 四、使用示例 ```bash mysh> notepad # 启动记事本 mysh> calc # 启动计算器 mysh> exit # 退出Shell ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值