常用的linux指令基本都支持命令行参数 例如 :
ls -l
rm -r
rm -f
cp -r
那么 这些参数都是如何去被应用程序获取的呢? 学习记录一下
1. shell 脚本
1.1 shell 脚本获得传入的参数
shell 脚本部分的数据处理是分为 传入和解析
对于参数的传入 一个简单的例子就是菜鸟教程中的例子 :
https://www.runoob.com/linux/linux-shell-passing-arguments.html
#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
以下也是引自 菜鸟教程
关于参数解析部分 shell 的解释器提供了一个成熟的解析方法 getopts , 使用该函数你可以去解析复杂的参数。
关于这部分的总结 可以参考:
https://blog.csdn.net/wdz306ling/article/details/79974377
#!/bin/bash
# auth: https://blog.csdn.net/wdz306ling/article/details/79974377
status=off #定义变量status,初始值设置为off
filename="" #定义变量filename,用于保存选项参数(文件)
output="" #定义变量output,用于保存选项参数(目录)
Usage () { #定义函数Usage,输出脚本使用方法
echo "Usage"
echo "myscript [-h] [-v] [-f <filename>] [-o <filename>]"
exit -1
}
while getopts :hvf:o: varname #告诉getopts此脚本有-h、-v、-f、-o四个选项,-f和-o后面需要跟参数(没有选项时,getopts会设置一个退出状态FALSE,退出循环)
do
case $varname in
h)
echo "$varname"
Usage
exit
;;
v)
echo "$varname"
status=on
echo "$status"
exit
;;
f)
echo "$varname"
echo "$OPTARG"
filename=$OPTARG #将选项的参数赋值给filename
if [ ! -f $filename ];then #判断选项所跟的参数是否存在且是文件
echo "the source file $filename not exist!"
exit
fi
;;
o)
echo "$varname"
echo "$OPTARG"
output=$OPTARG #将选项参数赋值给output
if [ ! -d $output ];then #判断选项参数是否存在且是目录
echo "the output path $output not exist"
exit
fi
;;
:) #当选项后面没有参数时,varname的值被设置为(:),OPTARG的值被设置为选项本身
echo "$varname"
echo "the option -$OPTARG require an arguement" #提示用户此选项后面需要一个参数
exit 1
;;
?) #当选项不匹配时,varname的值被设置为(?),OPTARG的值被设置为选项本身
echo "$varname"
echo "Invaild option: -$OPTARG" #提示用户此选项无效
Usage
exit 2
;;
esac
done
1.2 shell 脚本获得环境变量
shell 脚本里面使用 环境变量就很简单了 直接 判断变量是否存在 然后打印变量名称就可以了
root@jeason:~/shell# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/opt/xtensa-esp32-elf/bin:/usr/loacl/go/bin:/usr/local/go/bin
root@jeason:~/shell#
关于这部分 可以参考 https://blog.csdn.net/p106786860/article/details/51318467
大佬们太多了 这些知识也太常了。
2. linux 的 c 程序
2. 1 linux 的 c 程序获得 入口参数
获得 命令行参数的方法如下 :
#include <stdio.h>
int main(int argc,char *argv[])
{
printf("argc = %d\n",argc);
for(int i = 0; i < argc ; i++ ){
printf("argv[%d] = %s\n",i,argv[i]);
}
printf("done !\n");
return 0;
}
root@jeason:~/shell# gcc 1.c
root@jeason:~/shell# ./a.out
argc = 1
argv[0] = ./a.out
done !
root@jeason:~/shell# ./a.out a b cd e f g h i j k
argc = 11
argv[0] = ./a.out
argv[1] = a
argv[2] = b
argv[3] = cd
argv[4] = e
argv[5] = f
argv[6] = g
argv[7] = h
argv[8] = i
argv[9] = j
argv[10] = k
done !
root@jeason:~/shell#
2. 1 linux 的 c 程序获取环境变量
环境变量的获取 也是非常简单的 只需要直接引入一个全局的指针数组即可,这个指针数组会以一个nullptr进行结尾 。
#include <stdio.h>
int main(int argc,char *argv[])
{
printf("argc = %d\n",argc);
for(int i = 0; i < argc ; i++ ){
printf("argv[%d] = %s\n",i,argv[i]);
}
printf("done !\n");
extern char **environ;
while(*environ){
printf("%s\n",*environ ++);
}
return 0;
}
root@jeason:~/shell# gcc 1.c
root@jeason:~/shell# ./a.out a b cd e f g h i j k
argc = 11
argv[0] = ./a.out
argv[1] = a
argv[2] = b
argv[3] = cd
argv[4] = e
argv[5] = f
argv[6] = g
argv[7] = h
argv[8] = i
argv[9] = j
argv[10] = k
done !
LD_LIBRARY_PATH=:/usr/local/lib/
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
SSH_CONNECTION=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx# 保护处理
LESSCLOSE=/usr/bin/lesspipe %s %s
LANG=en_US.UTF-8
DISPLAY=localhost:11.0
S_COLORS=auto
XDG_SESSION_ID=17020
USER=root
PWD=/root/shell
HOME=/root
GOROOT=/usr/local/go
SSH_CLIENT=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx# 保护处理
LIBVIRT_DEFAULT_URI=qemu:///system
SSH_TTY=/dev/pts/2
MAIL=/var/mail/root
TERM=xterm
SHELL=/bin/bash
SHLVL=1
LOGNAME=root
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
XDG_RUNTIME_DIR=/run/user/0
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/opt/xtensa-esp32-elf/bin:/usr/loacl/go/bin:/usr/local/go/bin
LESSOPEN=| /usr/bin/lesspipe %s
OLDPWD=/root
_=./a.out
当然 关于参数的处理和解析的部分 我这里就没有去进行演示了 可以给大家复制一个开源库的处理方案供大家参考
demo 1
// soem 的FOE 升级demo 关于参数 可以看 usage部分的打印。
int main(int argc, char *argv[])
{
printf("SOEM (Simple Open EtherCAT Master)\nFirmware update example\n");
if (argc > 3)
{
argslave = atoi(argv[2]);
boottest(argv[1], argslave, argv[3]);
}
else
{
printf("Usage: firm_update ifname1 slave fname\n");
printf("ifname = eth0 for example\n");
printf("slave = slave number in EtherCAT order 1..n\n");
printf("fname = binary file to store in slave\n");
printf("CAUTION! Using the wrong file can result in a bricked slave!\n");
}
printf("End program\n");
return (0);
}
demo 2
int main(int argc, char *argv[])
{
ec_adaptert * adapter = NULL;
printf("SOEM (Simple Open EtherCAT Master)\nSlaveinfo\n");
if (argc > 1)
{
if ((argc > 2) && (strncmp(argv[2], "-sdo", sizeof("-sdo")) == 0)) printSDO = TRUE;
if ((argc > 2) && (strncmp(argv[2], "-map", sizeof("-map")) == 0)) printMAP = TRUE;
/* start slaveinfo */
strcpy(ifbuf, argv[1]);
slaveinfo(ifbuf);
}
else
{
printf("Usage: slaveinfo ifname [options]\nifname = eth0 for example\nOptions :\n -sdo : print SDO info\n -map : print mapping\n");
printf ("Available adapters\n");
adapter = ec_find_adapters ();
while (adapter != NULL)
{
printf ("Description : %s, Device to use for wpcap: %s\n", adapter->desc,adapter->name);
adapter = adapter->next;
}
}
printf("End program\n");
return (0);
}