Browse Source

[msh]implement tail command

Meco Man 4 years ago
parent
commit
7fd22c9546
1 changed files with 126 additions and 26 deletions
  1. 126 26
      components/finsh/msh_file.c

+ 126 - 26
components/finsh/msh_file.c

@@ -6,6 +6,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2015-09-25     Bernard      the first verion for FinSH
+ * 2021-06-09     Meco Man     implement tail command
  */
 
 #include <rtthread.h>
@@ -146,7 +147,7 @@ int msh_exec_script(const char *cmd_line, int size)
 extern char working_directory[];
 #endif
 
-int cmd_ls(int argc, char **argv)
+static int cmd_ls(int argc, char **argv)
 {
     extern void ls(const char *pathname);
 
@@ -165,9 +166,9 @@ int cmd_ls(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_ls, __cmd_ls, List information about the FILEs.);
+MSH_CMD_EXPORT_ALIAS(cmd_ls, ls, List information about the FILEs.);
 
-int cmd_cp(int argc, char **argv)
+static int cmd_cp(int argc, char **argv)
 {
     void copy(const char *src, const char *dst);
 
@@ -183,9 +184,9 @@ int cmd_cp(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_cp, __cmd_cp, Copy SOURCE to DEST.);
+MSH_CMD_EXPORT_ALIAS(cmd_cp, cp, Copy SOURCE to DEST.);
 
-int cmd_mv(int argc, char **argv)
+static int cmd_mv(int argc, char **argv)
 {
     if (argc != 3)
     {
@@ -242,9 +243,9 @@ int cmd_mv(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_mv, __cmd_mv, Rename SOURCE to DEST.);
+MSH_CMD_EXPORT_ALIAS(cmd_mv, mv, Rename SOURCE to DEST.);
 
-int cmd_cat(int argc, char **argv)
+static int cmd_cat(int argc, char **argv)
 {
     int index;
     extern void cat(const char *filename);
@@ -263,7 +264,7 @@ int cmd_cat(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_cat, __cmd_cat, Concatenate FILE(s));
+MSH_CMD_EXPORT_ALIAS(cmd_cat, cat, Concatenate FILE(s));
 
 static void directory_delete_for_msh(const char *pathname, char f, char v)
 {
@@ -329,7 +330,7 @@ static void directory_delete_for_msh(const char *pathname, char f, char v)
     }
 }
 
-int cmd_rm(int argc, char **argv)
+static int cmd_rm(int argc, char **argv)
 {
     int index, n;
     char f = 0, r = 0, v = 0;
@@ -399,10 +400,10 @@ int cmd_rm(int argc, char **argv)
     }
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_rm, __cmd_rm, Remove(unlink) the FILE(s).);
+MSH_CMD_EXPORT_ALIAS(cmd_rm, rm, Remove(unlink) the FILE(s).);
 
 #ifdef DFS_USING_WORKDIR
-int cmd_cd(int argc, char **argv)
+static int cmd_cd(int argc, char **argv)
 {
     if (argc == 1)
     {
@@ -418,17 +419,17 @@ int cmd_cd(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_cd, __cmd_cd, Change the shell working directory.);
+MSH_CMD_EXPORT_ALIAS(cmd_cd, cd, Change the shell working directory.);
 
-int cmd_pwd(int argc, char **argv)
+static int cmd_pwd(int argc, char **argv)
 {
     rt_kprintf("%s\n", working_directory);
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_pwd, __cmd_pwd, Print the name of the current working directory.);
+MSH_CMD_EXPORT_ALIAS(cmd_pwd, pwd, Print the name of the current working directory.);
 #endif
 
-int cmd_mkdir(int argc, char **argv)
+static int cmd_mkdir(int argc, char **argv)
 {
     if (argc == 1)
     {
@@ -442,9 +443,9 @@ int cmd_mkdir(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkdir, __cmd_mkdir, Create the DIRECTORY.);
+MSH_CMD_EXPORT_ALIAS(cmd_mkdir, mkdir, Create the DIRECTORY.);
 
-int cmd_mkfs(int argc, char **argv)
+static int cmd_mkfs(int argc, char **argv)
 {
     int result = 0;
     char *type = "elm"; /* use the default file system type as 'fatfs' */
@@ -474,10 +475,10 @@ int cmd_mkfs(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkfs, __cmd_mkfs, format disk with file system);
+MSH_CMD_EXPORT_ALIAS(cmd_mkfs, mkfs, format disk with file system);
 
 extern struct dfs_filesystem filesystem_table[];
-int cmd_mount(int argc, char *argv[])
+static int cmd_mount(int argc, char **argv)
 {
     if (argc == 1)
     {
@@ -522,10 +523,10 @@ int cmd_mount(int argc, char *argv[])
         return -1;
     }
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_mount, __cmd_mount, mount <device> <mountpoint> <fstype>);
+MSH_CMD_EXPORT_ALIAS(cmd_mount, mount, mount <device> <mountpoint> <fstype>);
 
 /* unmount the filesystem from the specified mountpoint */
-int cmd_umount(int argc, char *argv[])
+static int cmd_umount(int argc, char **argv)
 {
     char *path = argv[1];
 
@@ -547,10 +548,10 @@ int cmd_umount(int argc, char *argv[])
         return 0;
     }
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_umount, __cmd_umount, Unmount device from file system);
+MSH_CMD_EXPORT_ALIAS(cmd_umount, umount, Unmount device from file system);
 
 extern int df(const char *path);
-int cmd_df(int argc, char **argv)
+static int cmd_df(int argc, char **argv)
 {
     if (argc != 2)
     {
@@ -570,9 +571,9 @@ int cmd_df(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_df, __cmd_df, disk free);
+MSH_CMD_EXPORT_ALIAS(cmd_df, df, disk free);
 
-int cmd_echo(int argc, char **argv)
+static int cmd_echo(int argc, char **argv)
 {
     if (argc == 2)
     {
@@ -600,7 +601,106 @@ int cmd_echo(int argc, char **argv)
 
     return 0;
 }
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file);
+MSH_CMD_EXPORT_ALIAS(cmd_echo, echo, echo string to file);
+
+static int cmd_tail(int argc, char **argv)
+{
+    int fd;
+    char c = RT_NULL;
+    char *file_name = RT_NULL;
+    rt_uint32_t total_lines = 0;
+    rt_uint32_t target_line = 0;
+    rt_uint32_t current_line = 0;
+    rt_uint32_t required_lines = 0;
+    rt_uint32_t after_xxx_line = 0;
+
+    if(argc < 2)
+    {
+        rt_kprintf("Usage: tail [-n numbers] <filename>\n");
+        return -1;
+    }
+    else if(argc == 2)
+    {
+        required_lines = 10; /* default: 10 lines from tail */
+        file_name = argv[1];
+    }
+    else if(rt_strcmp(argv[1], "-n") == 0)
+    {
+        if(argv[2][0] != '+')
+        {
+            required_lines = atoi(argv[2]);
+        }
+        else
+        {
+            after_xxx_line = atoi(&argv[2][1]); /* eg: +100, to get the 100 */
+        }
+        file_name = argv[3];
+    }
+    else
+    {
+        rt_kprintf("Usage: tail [-n numbers] <filename>\n");
+        return -1;
+    }
+
+    fd = open(file_name, O_RDONLY);
+    if (fd < 0)
+    {
+        rt_kprintf("File doesn't exist\n");
+        return -1;
+    }
+
+    while ((read(fd, &c, sizeof(char))) > 0)
+    {
+        if (c == '\n')
+        {
+            total_lines++;
+        }
+    }
+
+    rt_kprintf("\nTotal Number of lines:%d\n", total_lines);
+
+    if(after_xxx_line != 0)
+    {
+        if(total_lines > after_xxx_line)
+        {
+            required_lines = total_lines - after_xxx_line;
+        }
+        else
+        {
+            rt_kprintf("\nError:Required lines are more than total number of lines\n");
+            close(fd);
+            return -1;
+        }
+    }
+
+    if (required_lines > total_lines)
+    {
+        rt_kprintf("\nError:Required lines are more than total number of lines\n");
+        close(fd);
+        return -1;
+    }
+    rt_kprintf("Required Number of lines:%d\n", required_lines);
+
+    target_line = total_lines - required_lines;
+    lseek(fd, 0, SEEK_SET); /* back to head */
+
+    while ((read(fd, &c, sizeof(char))) > 0)
+    {
+        if (c == '\n')
+        {
+            current_line++;
+        }
+        if (current_line > target_line)
+        {
+            rt_kprintf("%c", c);
+        }
+    }
+    rt_kprintf("\n");
+
+    close(fd);
+    return 0;
+}
+MSH_CMD_EXPORT_ALIAS(cmd_tail, tail, print the last N-lines data of the given file);
 
 #endif /* defined(FINSH_USING_MSH) && defined(RT_USING_DFS) */