linuxsock文件
『壹』 linux下socket 網路編程(客戶端向伺服器端發送文件) 求源代碼 大哥大姐幫幫忙 ,。。謝謝
不知道是樓下還是樓上,他用的事windows的套接字貌似,不過過程是一樣的,在Linux下面使用的函數名字不同罷了,客戶端向伺服器端發送文件,過程其實很簡單:
1.客戶端向伺服器端發送傳輸文件的請求(可攜帶一些所傳文件的大小之類的基本信息);
2.伺服器端接收請求(根據文件信息看是否能夠接受請求);
3.客戶端發送文件(如果接收到server的yes響應,那麼就傳送);
4.伺服器端接收文件(寫入到指定目錄的文件夾);
你需要先簡單了解過程,在弄清除Linux下面對socket的操作(其實就類似於對文件的操作)。
如果實在自己寫不出可以:email:[email protected]
『貳』 Linux fd 系列 — socket fd 是什麼
socket fd 是Linux系統中一種用於網路通信的文件描述符,實質上是一種文件句柄。以下是關於socket fd的詳細解釋:
定義與用途:
- socket fd在客戶端和服務端的C/S編程模式中被廣泛使用,用於實現網路數據的讀寫操作。
- 它與文件句柄在功能上並無本質區別,都能實現基本的I/O操作。
與文件描述符的關系:
- socket fd與文件描述符在Linux系統中具有相似的地位和作用,都用於標識和訪問文件或網路資源。
- 可以通過查看進程的文件描述符列表來找到socket fd,其名稱通常包含「socket:[編號]」的形式。
網路通信的實現:
- socket fd是網路通信的基石,它允許程序通過socket介面與網路進行交互。
- 在進行網路編程時,程序員通常使用socket函數創建socket fd,然後通過讀寫操作來發送和接收數據。
與TCP/IP協議棧的關系:
- 雖然TCP/IP協議棧是網路通信的基礎,但在進行網路編程時,程序員更關心的是操作系統的socket介面。
- socket fd為程序員提供了一個與TCP/IP協議棧交互的簡化介面,使得網路通信更加直觀和實用。
監聽套接字與普通套接字:
- 監聽套接字用於管理連接的建立,它關注連接隊列的非空狀態。
- 普通套接字用於數據流傳輸,它關注可讀和可寫事件。
sockfs文件系統:
- Linux內核通過實現sockfs文件系統來使socket fd具備文件句柄的語義。
- sockfs為socket提供了統一的介面,使得socket的I/O操作與其他文件句柄保持一致。
socket編程的關鍵函數:
- 服務端主要涉及socket、bind、listen、accept等函數。
- 客戶端則通常使用socket、connect等函數。
- 這些函數共同構成了socket編程的基礎,使得程序員能夠方便地創建和管理網路通信。
『叄』 如何查看linux用戶主目錄下的文件
在沒有圖形界面的Linux中需要查看一個文件的內容,這里分享下查找方法。
1、首先在電腦中打開Putty軟體,連接上Linux,如下圖所示。
『肆』 linux下socket 網路編程(客戶端向伺服器端發送文件) 求源代碼 大哥大姐幫幫忙 。。謝謝
server:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <syslog.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAXDATASIZE 1024
#define SERVPORT 19999
#define BACKLOG 10
int SendFileToServ(const char *path, const char *FileName, const char *ip)
{
#define PORT 20002
int sockfd;
int recvbytes;
char buf[MAXDATASIZE];
char send_str[MAXDATASIZE];
char filepath[128] = {0};
struct sockaddr_in serv_addr;
FILE *fp;
sprintf(filepath, "%s%s", path, FileName);
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
return 1;
}
bzero(&serv_addr,sizeof(struct sockaddr_in));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(PORT);
inet_aton(ip, &serv_addr.sin_addr);
int IErrCount = 0;
again:
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)
{
if (5 == IErrCount)
return 1;
IErrCount++;
perror("connect");
sleep(2);
goto again;
}
//if ((fp = fopen(FileName, "rb")) == NULL)
if ((fp = fopen(filepath, "rb")) == NULL)
{
perror("fopen ");
return 1;
}
recvbytes = write(sockfd, FileName, strlen(FileName));
recvbytes = read(sockfd, buf, MAXDATASIZE);
if (!memcmp(buf, "sendmsg", 7))
{
while(fgets(send_str, MAXDATASIZE, fp))
{
recvbytes = write(sockfd, send_str, strlen(send_str));
recvbytes = read(sockfd, buf, MAXDATASIZE);
if (recvbytes <= 0)
{
fclose(fp);
close(sockfd);
return 1;
}
if (memcmp(buf, "goon", 4))
{
fclose(fp);
close(sockfd);
return 1;
}
}
recvbytes = write(sockfd, "end", 3);
}
else
{
fclose(fp);
close(sockfd);
return 1;
}
memset(buf, 0, MAXDATASIZE);
if (read(sockfd, buf, MAXDATASIZE) <= 0)
{
close(sockfd);
return 2;
}
char *Eptr = "nginx reload error";
//printf("bf[%s]\n", buf);
int ret;
ret = strncmp(buf, Eptr, strlen(Eptr));
//printf("%d\n", ret);
if (!ret)
{
close(sockfd);
return 2;
}
close(sockfd);
return 0;
}
int mysyslog(const char * msg)
{
FILE *fp;
if ((fp = fopen("/tmp/tmp.log", "a+")) == NULL)
{
return 0;
}
fprintf(fp, "[%s]\n", msg);
fclose(fp);
return 0;
}
static void quit_handler(int signal)
{
kill(0, SIGUSR2);
syslog( LOG_NOTICE, "apuserv quit...");
// do something exit thing ,such as close socket ,close mysql,free list
// .....
//i end
exit(0);
}
static int re_conf = 0;
static void reconf_handler(int signal)
{
re_conf=1;
syslog(LOG_NOTICE,"apuserv reload configure file .");
// 請在循環體中判斷,如果re_conf == 1,請再次載入配置文件。
}
static int isrunning(void)
{
int fd;
int ret;
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0;
const char *lckfile = "/tmp/apuserv.lock";
fd = open(lckfile,O_WRONLY|O_CREAT);
if (fd < 0) {
syslog(LOG_ERR,"can not create lock file: %s\n",lckfile);
return 1;
}
if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {
ret = fcntl(fd,F_GETLK,&lock);
if (lock.l_type != F_UNLCK) {
close(fd);
return lock.l_pid;
}
else {
fcntl(fd,F_SETLK,&lock);
}
}
return 0;
}
int MyHandleBuff(const char *buf, char *str, char *FileName, char *pth)
{
sscanf(buf, "%s %s %s", pth, FileName, str);
printf("path=%s\nfilename=%s\nip=%s\n", pth, FileName, str);
return 0;
}
int main(int argc, char **argv)
{
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr,remote_addr;
char buff[MAXDATASIZE];
int recvbytes;
#if 1
int pid ;
char ch ;
int ret;
int debug = 0;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, quit_handler);
syslog(LOG_NOTICE,"apuserver start....");
while ((ch = getopt(argc, argv, "dhV")) != -1) {
switch (ch) {
case 'd':
debug = 1;
break;
case 'V':
printf("Version:%s\n","1.0.0");
return 0;
case 'h':
printf(" -d use daemon mode\n");
printf(" -V show version\n");
return 0;
default:
printf(" -d use daemon mode\n");
printf(" -V show version\n");
}
}
if (debug && daemon(0,0 ) ) {
return -1;
}
if (isrunning()) {
fprintf(stderr, "apuserv is already running\n");
syslog(LOG_INFO,"apuserv is already running\n");
exit(0);
}
while (1) {
pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
break;
while ((ret = waitpid(pid, NULL, 0)) != pid) {
syslog(LOG_NOTICE, "waitpid want %d, but got %d", pid, ret);
if (ret < 0)
syslog(LOG_NOTICE, "waitpid errno:%d", errno);
}
kill(0, SIGUSR2);
sleep(1);
syslog(LOG_NOTICE,"restart apuserver");
}
signal(SIGHUP, reconf_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1,SIG_IGN);
signal(SIGUSR2, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#endif
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
int nret;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)
{
perror("falied accept");
continue;
}
memset(buff, 0, MAXDATASIZE);
recvbytes = read(client_fd, buff, MAXDATASIZE);
char str[16] = {0};
char FileName[128] = {0};
char path[128] = {0};
MyHandleBuff(buff, str, FileName, path);
if (recvbytes > 0)
{
nret = SendFileToServ(path, FileName, str);
printf("nret[%d]\n", nret);
if (1 == nret)
write(client_fd, "send file error", 15);
else if(2 == nret)
write(client_fd, "reload nginx error", 18);
else
write(client_fd, "succ", 4);
}
close(client_fd);
}
}
_________________________________________________
client:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <syslog.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAXDATASIZE 1024
#define SERVPORT 20002
#define BACKLOG 10
int mysyslog(const char * msg)
{
FILE *fp;
if ((fp = fopen("/tmp/tmp.log", "a+")) == NULL)
{
return 0;
}
fprintf(fp, "[%s]\n", msg);
fclose(fp);
return 0;
}
static void quit_handler(int signal)
{
kill(0, SIGUSR2);
syslog( LOG_NOTICE, "apuserv quit...");
// do something exit thing ,such as close socket ,close mysql,free list
// .....
//i end
exit(0);
}
static int re_conf = 0;
static void reconf_handler(int signal)
{
re_conf=1;
syslog(LOG_NOTICE,"apuserv reload configure file .");
// ????·???????1nf == 1£???′μ?????
static int isrunning(void)
{
int fd;
int ret;
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0;
const char *lckfile = "/tmp/dstserver.lock";
fd = open(lckfile,O_WRONLY|O_CREAT);
if (fd < 0) {
syslog(LOG_ERR,"can not create lock file: %s\n",lckfile);
return 1;
}
if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {
ret = fcntl(fd,F_GETLK,&lock);
if (lock.l_type != F_UNLCK) {
close(fd);
return lock.l_pid;
}
else {
fcntl(fd,F_SETLK,&lock);
}
}
return 0;
}
int main(int argc, char **argv)
{
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr,remote_addr;
char buff[MAXDATASIZE];
int recvbytes;
#if 1
int pid ;
char ch ;
int ret;
int debug = 0;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, quit_handler);
syslog(LOG_NOTICE,"dstserver start....");
while ((ch = getopt(argc, argv, "dhV")) != -1) {
switch (ch) {
case 'd':
debug = 1;
break;
case 'V':
printf("Version:%s\n","1.0.0");
return 0;
case 'h':
printf(" -d use daemon mode\n");
printf(" -V show version\n");
return 0;
default:
printf(" -d use daemon mode\n");
printf(" -V show version\n");
}
}
if (debug && daemon(0,0 ) ) {
return -1;
}
if (isrunning()) {
fprintf(stderr, "dstserver is already running\n");
syslog(LOG_INFO,"dstserver is already running\n");
exit(0);
}
while (1) {
pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
break;
while ((ret = waitpid(pid, NULL, 0)) != pid) {
syslog(LOG_NOTICE, "waitpid want %d, but got %d", pid, ret);
if (ret < 0)
syslog(LOG_NOTICE, "waitpid errno:%d", errno);
}
kill(0, SIGUSR2);
sleep(1);
syslog(LOG_NOTICE,"restart apuserver");
}
signal(SIGHUP, reconf_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1,SIG_IGN);
signal(SIGUSR2, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#endif
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
char filepath[MAXDATASIZE]= {0};
FILE *fp;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)
{
perror("falied accept");
continue;
}
memset(buff, 0, MAXDATASIZE);
recvbytes = read(client_fd, buff, MAXDATASIZE);
sprintf(filepath, "/etc/nginx/url_rule/%s", buff);
if ((fp = fopen(filepath, "wb")) == NULL)
{
perror("fopen");
close(client_fd);
continue;
}
write(client_fd, "sendmsg", 7);
while(read(client_fd, buff, MAXDATASIZE))
{
if (!memcmp(buff, "end", 3))
{
fclose(fp);
break;
}
else
{
fprintf(fp, "%s", buff);
write(client_fd, "goon", 4);
}
}
//system("nginx -s reload");
char *Sptr = "nginx reload succ";
char *Eptr = "nginx reload error";
int ret;
ret = system("nginx -s reload");
printf("ret[%d]\n", ret);
if (ret != 0)
{
write(client_fd, Eptr, strlen(Eptr));
}
else
{
write(client_fd, Sptr, strlen(Sptr));
}
close(client_fd);
}
}
以前寫的:內容忘記了。不是很復雜你可以自己看!
『伍』 Linux系統中的文件類型及文件擴展名詳解
Linux文件類型和Linux文件的文件名所代表的意義是兩個不同的概念。我們通過一般應用程序而創建的比如file.txt、file.tar.gz ,這些文件雖然要用不同的程序來打開,但放在Linux文件類型中衡量的話,大多是常規文件(也被稱為普通文件)。
一.文件類型
Linux文件類型常見的有:普通文件、目錄文件、字元設備文件和塊設備文件、符號鏈接文件等,現在我們進行一個簡要的說明。
1.普通文件
我們用ls-lh來查看某個文件的屬性,可以看到有類似-rwxrwxrwx,值得注意的是第一個符號是-,這樣的文件在Linux中就是普通文件。這些文件一般是用一些相關的應用程序創建,比如圖像工具、文檔工具、歸檔工具.......或cp工具等。這類文件的刪除方式是用rm命令。另外,依照文件的內容,又大略可以分為:
1>.純文本檔(ASCII):
這是Linux系統中最多的一種文件類型,稱為純文本檔是因為內容為我們人類可以直接讀到的數據,例如數字、字母等等。幾乎只要我們可以用來做為設定的文件都屬於這一種文件類型。舉例來說,你可以用命令:cat~/.bashrc來看到該文件的內容。(cat是將一個文件內容讀出來的指令).
2>.二進制文件(binary):
Linux系統其實僅認識且可以執行二進制文件(binaryfile)。Linux當中的可執行文件(scripts,文字型批處理文件不算)就是這種格式的文件。剛剛使用的命令cat就是一個binaryfile。
3>.數據格式文件(data):
有些程序在運作的過程當中會讀取某些特定格式的文件,那些特定格式的文件可以被稱為數據文件(datafile)。舉例來說,我們的Linux在使用者登錄時,都會將登錄的數據記錄在/var/log/wtmp那個文件內,該文件是一個datafile,他能夠透過last這個指令讀出來!但是使用cat時,會讀出亂碼~因為他是屬於一種特殊格式的文件?
2.目錄文件
當我們在某個目錄下執行,看到有類似drwxr-xr-x,這樣的文件就是目錄,目錄在Linux是一個比較特殊的文件。注意它的第一個字元是d。創建目錄的命令可以用mkdir命令,或cp命令,cp可以把一個目錄復制為另一個目錄。刪除用rm或rmdir命令。
3.字元設備或塊設備文件
如時您進入/dev目錄,列一下文件,會看到類似如下的:
復制代碼代碼如下:[root@localhost ~]# ls -al /dev/tty
crw-rw-rw- 1 root tty 5, 0 11-03 15:11 /dev/tty
[root@localhost ~]# ls -la /dev/sda1
brw-r----- 1 root disk 8, 1 11-03 07:11 /dev/sda1
我們看到/dev/tty的屬性是crw-rw-rw-,注意前面第一個字元是c,這表示字元設備文件。比如貓等串口設備。我們看到/dev/sda1的屬性是brw-r-----,注意前面的第一個字元是b,這表示塊設備,比如硬碟,光碟機等設備。
這個種類的文件,是用mknode來創建,用rm來刪除。目前在最新的Linux發行版本中,我們一般不用自己來創建設備文件。因為這些文件是和內核相關聯的。
與系統周邊及儲存等相關的一些文件,通常都集中在/dev這個目錄之下!通常又分為兩種:
區塊(block)設備檔:
就是一些儲存數據,以提供系統隨機存取的介面設備,舉例來說,硬碟與軟盤等就是啦!你可以隨機的在硬碟的不同區塊讀寫,這種裝置就是成組設備!你可以自行查一下/dev/sda看看,會發現第一個屬性為[b]!
字元(character)設備文件:
亦即是一些串列埠的介面設備,例如鍵盤、滑鼠等等!這些設備的特色就是一次性讀取的,不能夠截斷輸出。舉例來說,你不可能讓滑鼠跳到另一個畫面,而是滑動到另一個地方!第一個屬性為[c]。
4.數據介面文件(sockets):
數據介面文件(或者:套介面文件),這種類型的文件通常被用在網路上的數據承接了。我們可以啟動一個程序來監聽客戶端的要求,而客戶端就可以透過這個socket來進行數據的溝通了。第一個屬性為[s],最常在/var/run這個目錄中看到這種文件類型了。
例如:當我們啟動MySQL伺服器時,會產生一個mysql.sock的文件。
復制代碼代碼如下:[root@localhost ~]# ls -lh /var/lib/mysql/mysql.sock
srwxrwxrwx 1 mysql mysql 0 04-19 11:12 /var/lib/mysql/mysql.sock
注意這個文件的屬性的第一個字元是s。
5.符號鏈接文件:
當我們查看文件屬性時,會看到有類似lrwxrwxrwx,注意第一個字元是l,這類文件是鏈接文件。是通過ln-s源文件名新文件名。上面是一個例子,表示setup.log是install.log的軟鏈接文件。怎麼理解呢?這和Windows操作系統中的快捷方式有點相似。
符號鏈接文件的創建方法舉例:
復制代碼代碼如下:[root@localhost test]# ls -lh log2012.log
-rw-r--r-- 1 root root 296K 11-13 06:03 log2012.log
[root@localhost test]# ln -s log2012.log linklog.log
[root@localhost test]# ls -lh *.log
lrwxrwxrwx 1 root root 11 11-22 06:58 linklog.log -> log2012.log
-rw-r--r-- 1 root root 296K 11-13 06:03 log2012.log
6.數據輸送文件(FIFO,pipe):
FIFO也是一種特殊的文件類型,他主要的目的在解決多個程序同時存取一個文件所造成的錯誤問題。FIFO是first-in-first-out的縮寫。第一個屬性為[p]。
二.Linux文件擴展名
1.擴展名類型
基本上,Linux的文件是沒有所謂的擴展名的,一個Linux文件能不能被執行,與他的第一欄的十個屬性有關,與檔名根本一點關系也沒有。這個觀念跟Windows的情況不相同喔!在Windows底下,能被執行的文件擴展名通常是.com.exe.bat等等,而在Linux底下,只要你的許可權當中具有x的話,例如[-rwx-r-xr-x]即代表這個文件可以被執行。
不過,可以被執行跟可以執行成功是不一樣的~舉例來說,在root家目錄下的install.log是一個純文本檔,如果經由修改許可權成為-rwxrwxrwx後,這個文件能夠真的執行成功嗎?當然不行~因為他的內容根本就沒有可以執行的數據。所以說,這個x代表這個文件具有可執行的能力,但是能不能執行成功,當然就得要看該文件的內容.
雖然如此,不過我們仍然希望可以藉由擴展名來了解該文件是什麼東西,所以,通常我們還是會以適當的擴展名來表示該文件是什麼種類的。底下有數種常用的擴展名:
*.sh:腳本或批處理文件(scripts),因為批處理文件為使用shell寫成的,所以擴展名就編成.sh
*Z,*.tar,*.tar.gz,*.zip,*.tgz:經過打包的壓縮文件。這是因為壓縮軟體分別為gunzip,tar等等的,由於不同的壓縮軟體,而取其相關的擴展名!
*.html,*.php:網頁相關文件,分別代表HTML語法與PHP語法的網頁文件。.html的文件可使用網頁瀏覽器來直接開啟,至於.php的文件,則可以透過client端的瀏覽器來server端瀏覽,以得到運算後的網頁結果。
基本上,Linux系統上的文件名真的只是讓你了解該文件可能的用途而已,真正的執行與否仍然需要許可權的規范才行。例如雖然有一個文件為可執行文件,如常見的/bin/ls這個顯示文件屬性的指令,不過,如果這個文件的許可權被修改成無法執行時,那麼ls就變成不能執行。
上述的這種問題最常發生在文件傳送的過程中。例如你在網路上下載一個可執行文件,但是偏偏在你的Linux系統中就是無法執行!呵呵!那麼就是可能文件的屬性被改變了。不要懷疑,從網路上傳送到你的Linux系統中,文件的屬性與許可權確實是會被改變的。
2.Linux文件名長度限制:
在Linux底下,使用預設的Ext2/Ext3文件系統時,針對文件名長度限制為:
單一文件或目錄的最大容許文件名為255個字元
包含完整路徑名稱及目錄(/)之完整檔名為4096個字元
是相當長的檔名!我們希望Linux的文件名可以一看就知道該文件在幹嘛的,所以檔名通常是很長很長。
3.Linux文件名的字元的限制:
由於Linux在文字介面下的一些指令操作關系,一般來說,你在設定Linux底下的文件名時,最好可以避免一些特殊字元比較好!例如底下這些:
*?><;&![]|'"`(){}
因為這些符號在文字介面下,是有特殊意義的。另外,文件名的開頭為小數點「.」時,代表這個文件為隱藏文件!同時,由於指令下達當中,常常會使用到-option之類的選項,所以你最好也避免將文件檔名的開頭以-或+來命名。