我的代码在 Linux 上给出了环境变量
My code gives out Environment variables on Linux
有些代码可能没有任何意义,(也许我也很困惑)这是怎么发生的,为什么?
这段代码是为了其他目的,(我试图制作一个计算器,所以主要源代码 [几乎没有问题] 作为我的问题存在于这个网站上)我以某种方式破坏了它所以我修改了它并提取了代码最初打破了它。
我在 Kali 上测试过 Linux。
代码如下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
//Some of this might not make any sense, but its the way i was able to break it.. somehow
int main(int argc,char *argv[]) {
FILE *file = fopen(argv[2],"a");
if(file == NULL) {
printf("Error Opening File!");
return 1;
}
char ch;
int i;
printf("%i\n",argc);
printf("%i\n",argv);
while((ch = getopt(argc,argv,"d:"))!=EOF)
switch(ch) {
case 'd':
for(i=4; i<=48; i++) // This loop may vary on other system. On first run i used "i<=51" , and on different system, same os, its the mentioned condition
fprintf(file,"%s \n",argv[i]);
fclose(file);
break;
default:
fprintf(stderr,"No such command");
}
argc-=1;
argv+=1;
return 0;
}
以下结果是在 运行(原始源代码。此代码将其写入文件)上产生的:
value at argv=
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:
value at argv= XDG_MENU_PREFIX=gnome-
value at argv= LANG=en_IN
value at argv= GDM_LANG=en_IN
value at argv= MANAGERPID=793
value at argv= DISPLAY=:1
value at argv= INVOCATION_ID=3e7f771adfde4001af637f9527e9cc9d
value at argv= COLORTERM=truecolor
value at argv= USERNAME=root
value at argv= XDG_VTNR=2
value at argv= SSH_AUTH_SOCK=/run/user/0/keyring/ssh
value at argv= S_COLORS=auto
value at argv= XDG_SESSION_ID=3
value at argv= USER=root
value at argv= DESKTOP_SESSION=gnome
value at argv= PWD=/media/root/F89AF7139AF6CCDE
value at argv= HOME=/root
value at argv= JOURNAL_STREAM=9:19456
value at argv= SSH_AGENT_PID=945
value at argv= QT_ACCESSIBILITY=1
value at argv= XDG_SESSION_TYPE=x11
value at argv=
XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/
value at argv= XDG_SESSION_DESKTOP=gnome
value at argv=
DBUS_STARTER_ADDRESS=unix:path=/run/user/0/bus,guid=11c587e1337f9fb06858c2415bbac73a
value at argv= GTK_MODULES=gail:atk-bridge
value at argv= WINDOWPATH=2
value at argv= TERM=xterm-256color
value at argv= SHELL=/bin/bash
value at argv= VTE_VERSION=5002
value at argv= DBUS_STARTER_BUS_TYPE=session
value at argv= XDG_CURRENT_DESKTOP=GNOME
value at argv= GPG_AGENT_INFO=/run/user/0/gnupg/S.gpg-agent:0:1
value at argv= SHLVL=1
value at argv= XDG_SEAT=seat0
value at argv= LANGUAGE=en_IN:en
value at argv= WINDOWID=39845894
value at argv= GDMSESSION=gnome
value at argv= GNOME_DESKTOP_SESSION_ID=this-is-deprecated
value at argv= LOGNAME=root
value at argv=
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus,guid=11c587e1337f9fb06858c2415bbac73a
value at argv= XDG_RUNTIME_DIR=/run/user/0
value at argv= XAUTHORITY=/run/user/0/gdm/Xauthority
value at argv=
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
value at argv=
SESSION_MANAGER=local/kali:@/tmp/.ICE-unix/894,unix/kali:/tmp/.ICE-unix/894
value at argv= _=./a.out
value at argv= (null)
我接下来的问题是,环境变量到底是什么?为什么我会给我这样的结果?
// probably use one option at a time
//This code has some flaws, for example i didnt check if the file was opened
or not, etc, pardon me for it. This is the actual un-edited source of the
code.
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int add(int a,int b){
return a+b;
}
int subtract(int a, int b){
return a-b;
}
int main(int argc, char *argv[]){
FILE *file1 = fopen("Results.txt","a");
char ch;
int res;
while((ch=getopt(argc,argv,"a:s:"))!=EOF)
switch (ch){
case 'a':
res = add(atoi(optarg),atoi(argv[3]));
fprintf(file1,"%i\n",res);
break;
case 's':
res = subtract(atoi(optarg),atoi(argv[3]));
printf("%i \n",res);
fprintf(file1,"%i\n",res);
break;
default:
fprintf(stderr,"No such option");
return 1;
}
//THe commented out section produces weird behaviour...
//printf("Opind = %i, argc = %i, argv = %i \n",optind,argc,argv);
argc-=optind;
//printf("value at optarg = %i value at argv_3= %s \n",optarg,argv[3]);
argv+=optind;
//printf("Opind = %i, argc = %i, argv = %i \n",optind,argc,argv);
//printf("value at optarg = %i value at argv_3= %s \n",optarg,argv[1]);
fprintf(file1,"\nWritten to file\n");
fclose(file1);
return 0;
}
首先,超出数组范围会导致 undefined behavior。当您遍历 argv
数组而不检查例如i < argc
(除非您实际上在命令行上提供了超过 48 个参数)。
其次,为什么在超出argv
范围时打印环境变量,这是因为在POSIX系统(如Linux或macOS)上有一个[= main
函数的第三个 参数,通常称为 environ
。与 argv
类似,它是一个包含环境变量的字符串数组(以相同的方式声明,例如 char *environ[]
)。通过超出 argv
的范围,您将进入 environ
数组的内存。
在相关说明中,您使用 argv[2]
时没有检查参数是否确实存在,或者它不是您使用 getopt
解析的任何其他参数。不要那样做。
还要注意 getopt
函数 returns 和 int
。这实际上对于检查 -1
(不是 EOF
!)非常重要。
有些代码可能没有任何意义,(也许我也很困惑)这是怎么发生的,为什么? 这段代码是为了其他目的,(我试图制作一个计算器,所以主要源代码 [几乎没有问题] 作为我的问题存在于这个网站上)我以某种方式破坏了它所以我修改了它并提取了代码最初打破了它。
我在 Kali 上测试过 Linux。
代码如下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
//Some of this might not make any sense, but its the way i was able to break it.. somehow
int main(int argc,char *argv[]) {
FILE *file = fopen(argv[2],"a");
if(file == NULL) {
printf("Error Opening File!");
return 1;
}
char ch;
int i;
printf("%i\n",argc);
printf("%i\n",argv);
while((ch = getopt(argc,argv,"d:"))!=EOF)
switch(ch) {
case 'd':
for(i=4; i<=48; i++) // This loop may vary on other system. On first run i used "i<=51" , and on different system, same os, its the mentioned condition
fprintf(file,"%s \n",argv[i]);
fclose(file);
break;
default:
fprintf(stderr,"No such command");
}
argc-=1;
argv+=1;
return 0;
}
以下结果是在 运行(原始源代码。此代码将其写入文件)上产生的:
value at argv= 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:
value at argv= XDG_MENU_PREFIX=gnome-
value at argv= LANG=en_IN
value at argv= GDM_LANG=en_IN
value at argv= MANAGERPID=793
value at argv= DISPLAY=:1
value at argv= INVOCATION_ID=3e7f771adfde4001af637f9527e9cc9d
value at argv= COLORTERM=truecolor
value at argv= USERNAME=root
value at argv= XDG_VTNR=2
value at argv= SSH_AUTH_SOCK=/run/user/0/keyring/ssh
value at argv= S_COLORS=auto
value at argv= XDG_SESSION_ID=3
value at argv= USER=root
value at argv= DESKTOP_SESSION=gnome
value at argv= PWD=/media/root/F89AF7139AF6CCDE
value at argv= HOME=/root
value at argv= JOURNAL_STREAM=9:19456
value at argv= SSH_AGENT_PID=945
value at argv= QT_ACCESSIBILITY=1
value at argv= XDG_SESSION_TYPE=x11
value at argv= XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share/:/usr/share/
value at argv= XDG_SESSION_DESKTOP=gnome
value at argv= DBUS_STARTER_ADDRESS=unix:path=/run/user/0/bus,guid=11c587e1337f9fb06858c2415bbac73a
value at argv= GTK_MODULES=gail:atk-bridge
value at argv= WINDOWPATH=2
value at argv= TERM=xterm-256color
value at argv= SHELL=/bin/bash
value at argv= VTE_VERSION=5002
value at argv= DBUS_STARTER_BUS_TYPE=session
value at argv= XDG_CURRENT_DESKTOP=GNOME
value at argv= GPG_AGENT_INFO=/run/user/0/gnupg/S.gpg-agent:0:1
value at argv= SHLVL=1
value at argv= XDG_SEAT=seat0
value at argv= LANGUAGE=en_IN:en
value at argv= WINDOWID=39845894
value at argv= GDMSESSION=gnome
value at argv= GNOME_DESKTOP_SESSION_ID=this-is-deprecated
value at argv= LOGNAME=root
value at argv= DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus,guid=11c587e1337f9fb06858c2415bbac73a
value at argv= XDG_RUNTIME_DIR=/run/user/0
value at argv= XAUTHORITY=/run/user/0/gdm/Xauthority
value at argv= PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
value at argv= SESSION_MANAGER=local/kali:@/tmp/.ICE-unix/894,unix/kali:/tmp/.ICE-unix/894
value at argv= _=./a.out
value at argv= (null)
我接下来的问题是,环境变量到底是什么?为什么我会给我这样的结果?
// probably use one option at a time
//This code has some flaws, for example i didnt check if the file was opened
or not, etc, pardon me for it. This is the actual un-edited source of the
code.
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int add(int a,int b){
return a+b;
}
int subtract(int a, int b){
return a-b;
}
int main(int argc, char *argv[]){
FILE *file1 = fopen("Results.txt","a");
char ch;
int res;
while((ch=getopt(argc,argv,"a:s:"))!=EOF)
switch (ch){
case 'a':
res = add(atoi(optarg),atoi(argv[3]));
fprintf(file1,"%i\n",res);
break;
case 's':
res = subtract(atoi(optarg),atoi(argv[3]));
printf("%i \n",res);
fprintf(file1,"%i\n",res);
break;
default:
fprintf(stderr,"No such option");
return 1;
}
//THe commented out section produces weird behaviour...
//printf("Opind = %i, argc = %i, argv = %i \n",optind,argc,argv);
argc-=optind;
//printf("value at optarg = %i value at argv_3= %s \n",optarg,argv[3]);
argv+=optind;
//printf("Opind = %i, argc = %i, argv = %i \n",optind,argc,argv);
//printf("value at optarg = %i value at argv_3= %s \n",optarg,argv[1]);
fprintf(file1,"\nWritten to file\n");
fclose(file1);
return 0;
}
首先,超出数组范围会导致 undefined behavior。当您遍历 argv
数组而不检查例如i < argc
(除非您实际上在命令行上提供了超过 48 个参数)。
其次,为什么在超出argv
范围时打印环境变量,这是因为在POSIX系统(如Linux或macOS)上有一个[= main
函数的第三个 参数,通常称为 environ
。与 argv
类似,它是一个包含环境变量的字符串数组(以相同的方式声明,例如 char *environ[]
)。通过超出 argv
的范围,您将进入 environ
数组的内存。
在相关说明中,您使用 argv[2]
时没有检查参数是否确实存在,或者它不是您使用 getopt
解析的任何其他参数。不要那样做。
还要注意 getopt
函数 returns 和 int
。这实际上对于检查 -1
(不是 EOF
!)非常重要。