Linux環境下模擬shell終端:mybash、mysu、myclear
通常shell中執行命令的流程都是bash程序建立了一個子程序,然後子程序程序替換,替換為可執行的命令檔案。
1、mybash函式:輸出資訊的格式是:[使用者名稱@主機名所在檔案]$(root使用者:[使用者名稱@主機名所在檔案]#)。當所在檔案就是當前使用者的家目錄時顯示“~”。
那麼,該如何得到使用者名稱,主機名和當前所在檔名呢?
我們需要藉助下面這些函式:
uid_t geteuid(void)函式取得執行目前程序有效的使用者識別碼。有效的使用者識別碼用來決定程序執行的許可權,改變此值,程序可以獲得額外的許可權。
struct passwd *getpwuid(uid_t uid)函式通過使用者的uid查詢使用者的passwd資料。如果出錯時,它們都返回一個空指標並設定errno的值,使用者可以根據perror函式查看出錯的資訊。
struct passwd *getpwnam(const char *name)函式獲取使用者登入相關資訊,其中name是當前登入的使用者名稱。若成功,返回指標;若出錯或者達到檔案尾端,返回NULL。
int uname(struct utsname *name)函式把主機資訊寫入name引數指向的結構體中。
char *getcwd(char *buf, size_t size)函式把當前目錄的絕對地址儲存到 buff中,buff 的大小為 size。如果 size太小無法儲存該地址,返回 NULL 並設定 errno 為 ERANGE。可以採取令 buff 為 NULL並使 size 為負值來使 getcwd 呼叫 malloc 動態給 buff 分配,但是這種情況要特別注意使用後釋放緩衝以防止記憶體洩漏。
需注意的是:1.使用函式uname()得到的主機名“.”之後的部分是多餘的,需要進行額外的處理。2.getcwd()函式得到的是函式的絕對路徑,在顯示的資訊中只需要當前目錄的名字,需要進行處理。
程式碼實現:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#define LENTH 20
char *cmdArr[LENTH]={NULL};
int count = 0;
void out_flag()
{
char path[128] = {0};
if(NULL == getcwd(path, 128))
{
printf ("getcwd error\n");
return;
}
char dir[128] = {0};
char *p = strtok(path, "/");
while(p != NULL)
{
strcpy(dir, p);
p = strtok(NULL, "/");
}
if(strlen(dir) == 0)
{
strcpy(dir, "/");
}
struct passwd *pw = getpwuid(getuid());
if(pw == NULL)
{
printf ("error\n");
return;
}
if(strcmp(pw->pw_dir, getcwd(path, 128)) == 0)
{
memset(dir, 0, 128);
strcpy(dir, "~");
}
struct utsname host;
uname(&host);
char *hname = strtok(host.nodename, ".");
if(hname == NULL)
{
printf("error\n");
return;
}
char flag = '$';
if(pw->pw_uid == 0)
{
flag = '#';
}
printf("[%[email protected]%s %s]%c ", pw->pw_name, hname, dir, flag);
fflush(stdout);
}
2、mysu函式:su命令切換使用者成功後,su程序會新建一個子程序並把它替換為bash程序,su之後的命令都是在新建的bash裡執行的。
程式碼實現
int main(int argc,char *argv[])
{
char *user="root";//指標
if(argv[1]!=NULL)
{
user=argv[1];
struct passwd *p=NULL;
p=getpwnam(user);
if(p==NULL)
{
printf("not find username!\n");
return;
}
}
struct passwd *pw=getpwuid(getuid());
if(strcmp(pw->pw_name,"root")!=0)
{
char passwd[128]={0};
printf("Passwd:");
struct termios old,new;
tcgetattr(0,&old);
new=old;
new.c_lflag &= ~ECHO;
new.c_lflag &= ~ICANON;
tcsetattr(0,TCSANOW,&new);
char c=0;
int num=0;
while((c=getchar())!='\n')
{
if(c==127)
{
if(num>0)
{
passwd[--num]=0;
printf("\033[1D");
printf("\033[K");
}
continue;
}
printf("*");
fflush(stdout);
passwd[num++]=c;
}
tcsetattr(0,TCSANOW,&old);
printf("\n");
struct spwd *sp=getspnam(user);
assert(sp!=NULL);
char salt[128]={0};
int i=0;
int count =0;
for(;sp->sp_pwdp[i]!=0;i++)
{
salt[i]=sp->sp_pwdp[i];
if(salt[i]=='$')
{
count++;
if(count==3)
break;
}
}
char* p=crypt(passwd,salt);
assert(p!=NULL);
if(strcmp(p,sp->sp_pwdp)!=0)
{
printf("passwd error\n");
exit(0);
}
}
pid_t pid=fork();
assert(pid!=-1);
if(pid==0)
{
struct passwd *pw=getpwnam(user);
assert(pw!=NULL);
setuid(pw->pw_uid);
setenv("HOME",pw->pw_dir,1);
execl(pw->pw_shell,pw->pw_shell,(char *)0);
printf("error\n");
exit(0);
}
else
{
wait(NULL);
}
return 0;
}
3.myclear函式:printf(“033[%d;%dH”,0,0)代表清屏且回到原點(0,0)。
程式碼實現:
#include <stdio.h>
void main()
{
printf("033\[2J");
printf("033[%d;%dH",0,0);
}
注:mysu函式編譯時要用gcc -o su su.c -lcrypt
相關推薦
Linux環境下模擬shell終端:mybash、mysu、myclear
通常shell中執行命令的流程都是bash程序建立了一個子程序,然後子程序程序替換,替換為可執行的命令檔案。 1、mybash函式:輸出資訊的格式是:[使用者名稱@主機名所在檔案]$(root使用者:[使用者名稱@主機名所在檔案]#)。當所在檔案就是當前使用者
python 和linux環境下:音訊處理變頻變調的方法和框架
前戲——音樂基礎 聲音是靠波來傳播的,區別任何的聲音需要依據三個來區分:響度、音高和音色響度 音高:聲音具有確定的音高,聲音就可以使空氣以篤定的方式執行。低音就是頻率低。 一個樂音訊率是另外一個樂音的頻率的2倍,我就就稱為比它高八度,聲音的震動頻率=音源的振動頻率
Linux環境下編寫簡單的Shell
使用程序建立、等待、終止等知識自主實現簡單的Linuxshell命令列,Linux環境:CentOS7.3 程序建立 建立程序的方式 通常使用fork()函式來建立一個新程序,新程序為子程序,而原來的程序即為父程序。在Linux中fork()是一個非常重要的函式
Linux環境下Shell調用MySQL並實現定時任務
usr .sql 操作 default char star ted 空格 rontab 對於一些周期性事務,我們可以在Linux下,使用shell腳本調用mysql數據庫存儲過程,並設置定時任務。 本來是要mysql數據庫中創建事件任務來,定時執行存儲過程,做數據傳輸的。
Nginx 之一 伺服器的安裝部署(一): LInux 環境下 Nginx 伺服器的安裝和基本配置
一、編譯和安裝前的準備工作 本部落格依賴環境: Linux Ubuntu 16.04 1.1 足夠的磁碟空間 能夠裝得下 Nginx 的軟體包和安裝檔案, 這個基本都能滿足。 1.2 需要的工具 為了編譯 Nginx 原始碼, 需要安裝標準的 GCC 編譯器。
Linux環境下JDK配置:
因為最近需要在Linux環境下搭建CTS測試環境,查了好多次資料後總結了以下一些東西,寫點筆記留著以後自己看。 Linux環境下JDK配置: 1.獲取root許可權 sudo -s 或者sudo -i 2.在usr目錄下建立java安裝目錄 cd /usr mkdir java
【 Linux學習】Linux環境下利用wget下載https連結內容時報錯:無法本地校驗頒發者的許可權。 要以不安全的方式連線至 ,使用“--no-check-certificate”
一、問題描述 今天在CenterOS系統上使用wget命令下載一個https連結的內容時報錯,如下所示: [[email protected] /]# wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-
Linux環境下原始碼編譯和執行常用的兩個命令:pkg-config和ldconfig
最近一段時間在研究linux伺服器叢集的相關知識,打算基於corosync和pacemaker來搭建一個linux高可用叢集, 通過編譯原始碼包來了解其依賴的動態庫,在編譯的過程中遇到一些問題,總結一些,供大家以後參考(很通用哦): 我們
Linux環境下gcc靜態編譯/usr/bin/ld: cannot find -lc錯誤原因及解決方法 原因:
原因: 一般出現這個問題的時候,Makefile中肯定有-static選項。這其實是靜態連結時沒有找到libc.a。 解決方案: 需要安裝glibc-static.xxx.rpm,如glibc-static-2.12-1.107.el6_4.2.i686.rpm,或是yum install gli
Linux 環境下 Java jdk 安裝方法 注:此方法為 jdk.bin型別的jdk檔案
1、將jdk檔案放到一個目錄下 例如:jdk.bin 例如 /usr/java 放到了這個這個目錄下 2、然後利用命令檢視目錄下是否有此檔案 # cd /usr/java # ls 如果顯示檔案 jdk.bin 3、解壓jdk.bin檔案 # chmod 755 jdk.bin # ./jdk.b
Linux 環境下eclipse啟動出現錯誤:jvm terminated. exit code=13
想在Linux下啟動eclipse出現如題的錯誤,在網上找了很多資料,有很多是誤導。在stackoverflow上找到了正確解決方法,英文連線:http://stackoverflow.com/questions/4945178/cannot-run-eclipse-jvm
Linux環境下啟動jar包的shell
#! /bin/sh name="beautifulDistrict" Xmx=1024m Xms=1024m Xmn=512m PermSize=256m MaxPermSize=512m pid=${name}".pid" logName="all" jarName=`l
【Redis學習】:Linux環境下的Redis安裝與配置
安裝環境 redis是C語言開發的,安裝redis需要先將官網上下載的原始碼進行編譯,編譯依賴gcc環境,如果沒有gcc環境,需要安裝gcc。這個最好使用yum安裝,因為依賴關係比較多,自己不好找
在Ubuntu/Linux環境下使用MySQL:啟動和關閉MySQL服務
作業系統:Ubuntu 17.04 64位 MySQL版本:MySQL 5.7 一、啟動MySQL服務 使用以下命令來啟動MySQL: service mysql start 順便提一下,serv
linux環境下搭建Jenkins持續整合(Jenkins+git+shell+maven+tomact)
準備環境 jenkins.war包 ,jdk1.8 ,tomact , maven,git 1.Jenkins war包,下載地址https://jenkins.io/zh/download/ ,當然你可以通過wget 下載, 也可以通過xftp遠端傳輸 2.
Linux環境下的 pyenv的安裝
pyenvCentOS上安裝pyenv:在安裝pyenv前,需要先安裝如下的依賴包:在 CentOS/RHEL/Fedora 下:yum install readline readline-devel readline-static yum install openssl openssl-devel open
linux環境下部署zabbix3.2、模板、郵件告警詳細過程
-1 ice erer without zlib zip ever native item 服務端部署: 系統環境及軟件版本: Linux:release 6.3 zabbix:zabbix-3.2.5.tar.gz nginx:nginx-1.12.0.tar.gz ph
2.Linux環境下配置Solr4.10.3
margin 內容 src source -type alt 技術 tgz 安裝包 1.準備階段 操作系統:CentOS 6.8 安裝包:/home/test solr-4.10.3.tgz.tar IK Analyzer 2012FF_hf1.zip jdk-8u12
由一個簡單需求到Linux環境下的syslog、unix domain socket
message python domain 服務器 import 需求:回到頂部 工作中有一個在Linux(debian8)環境下運行的服務器程序,用python語言實現,代碼中有不同優先級的日誌需要記錄,開發的時候都是使用python的logging模塊輸出到文件,示例代碼如下:
(1)Jenkins Linux環境下的簡單搭建
linux java jenkins安裝部署 jdk apache-maven (1)Jenkins Linux環境下的簡單搭建 Jenkins是一個開源軟件項目,旨在提供一個開放易用的軟件平臺,使軟件的持續集成變成可能。----百度百科 這是一款基於Java開發的工具。種種