热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linuxbash命令行下实现可视化文件或文件夹浏览

Linuxbash命令行下实现可视化文件或文件夹浏览  有时候部署环境,需要配置文件路径或者载入相应的配置文件。这种情况下,如果用传统的手动修改配置的方式配置,会比较容易出意外(比
Linux bash 命令行下实现可视化文件或文件夹浏览

文章目录

  • 前言
  • 最终解决方案
    • 代码
    • 看起来像这样
    • 使用方式
      • 获取用户选择的文件/文件夹
      • 我怎么知道用户选择的是文件还是文件夹
    • 我可不可以在C等语言调用这个脚本啊
前言

  有时候部署环境,需要配置文件路径或者载入相应的配置文件。这种情况下,如果用传统的手动修改配置的方式配置,会比较容易出意外(比如中文符号和英文符号混淆、大小写错误、l和i混淆等)。
  这个时候,我解决的方式就是模仿Windows下常见的文件对话框,在下载文件、打开文件时Windows常见的文件对话框。与Windows不同的是,我要在命令行界面下使用图形化的对话框。写库是不可能写库的,我着急着用这个功能,所以就直接用了现成的dialog工具来完成。

最终解决方案

代码

  因为我是在部署环境的场景下使用,所以就不用C或C++写这个代码了,使用bash代码。依赖dialog,可以使用sudo yum install dialogsudo apt-get install dialog安装dialog。

#!/bin/bashERROR_CD=1# 文件夹无法进入ENTER_LABEL="选择文件/进入文件夹"DONE_LABEL="选择当前文件夹"TITLE="浏览"TIP="当前路径: "tmpfile=$(mktemp)functionshow(){localinit_dir=$(realpath"$1")if!cd"$init_dir";thenreturn$ERROR_CDfilocallist=$(ls -aQ)# -a 显示隐藏文件, -Q 每个文件左右两边添加双引号并转义特殊字符localold_IFS=$IFSIFS=$'\n'listarr=($list)# 按换行符分割IFS=$old_IFSlist=''foriin${!listarr[*]};do# 每一个文件, 添加修改日期和文件类型信息到右边list="$list${listarr[$i]}\"$(eval "date -d @\$(stat ${listarr[$i]} -c %Y) '+%Y-%m-%d %T'")$(eval"stat${listarr[$i]} -c %F")\""
	done
	eval "dialog --ok-label'$ENTER_LABEL' --cancel-label'$DONE_LABEL' --title'$TITLE' --menu'${TIP}${init_dir}'000$list2>'$tmpfile'"return0}functionnext_action(){localitem=$1if["$item"==""];then# 选择了当前文件夹, 直接输出当前路径到缓存文件echo"$(pwd)">"$tmpfile"return0filocaltyp=$(ls -ld"$item"|cut -c1)if["$typ"=="d"];then# 是目录, 进入
		browse_dir"$item"elif["$typ"=="l"];then# 是符号链接, 判断链接到的文件是目录还是其他locallnk=$(readlink"$item")if!cd"$(dirname"$lnk")";thenreturn$ERROR_CDfi
		next_action"$(basename"$lnk")"else# 其他当普通文件处理, 文件名输出到缓存文件echo"$(realpath"$item")">"$tmpfile"fi}functionbrowse_dir(){local statuslocalinit_dir=$1
	show"$init_dir"status=$?if[$status -ne0];thenreturn$statusfilocalitem=$(cat"$tmpfile")
	next_action"$item"}INIT_DIR=${1:-./}

browse_dir"$INIT_DIR"status=$?if[$status -ne0];thenexit$statusfiresult=$(cat"$tmpfile")rm -f"$tmpfile"echo"$result">&2exit0

看起来像这样

在这里插入图片描述

注:不同终端工具下显示的效果是不一样的。

使用方式

  假设上述代码保存到browse_dir.sh,并且已经添加可执行权限。

./browse_dir.sh

  如上即可显示一个文件对话框,初始路径为当前路径。
  如果需要设置初始路径,可以在参数指定,如:

./browse_dir.sh /home# 初始路径设置为 /home

获取用户选择的文件/文件夹

  我把用户选择放到了标准错误输出里了,也就是通过重定向标准错误输出到缓存文件,然后读取这个缓存文件就可以获取到用户的选择了。例如:

tmpfile=$(mktemp)
./browse_dir.sh /2>$tmpfilecat$tmpfilerm -f$tmpfile

  输出:
在这里插入图片描述
在这里插入图片描述

我怎么知道用户选择的是文件还是文件夹

  要判断用户选择的是文件还是文件夹,需要自行通过命令判断,如:

ls -ld<用户选择的结果>|cut -c1

  如果输出d表示用户选择的是文件夹,输出-表示用户选择的是文件。如:
在这里插入图片描述
  如上输出了-,所以表示是文件。
在这里插入图片描述
  如上输出了d,所以是文件夹。

我可不可以在C等语言调用这个脚本啊

  可以,调用的方法很多,如:

#include#includeintmain(){char tmp[11]="tmp.XXXXXX";char cmd[512]={0};char item[261]={0};char typ;
	FILE*tmpfile=NULL;int tmpfd=mkstemp(tmp);close(tmpfd);sprintf(cmd,"./browse_dir.sh / 2>%s", tmp);system(cmd);
	tmpfile=fopen(tmp,"rb");fread(item,260,1, tmpfile);fclose(tmpfile);strtok(item,"\n");fprintf(stdout,"你选择了: %s\n", item);fprintf(stdout,"它是一个: ");sprintf(cmd,"ls -ld %s | cut -c 1 >%s", item, tmp);system(cmd);
	tmpfile=fopen(tmp,"rb");fread(&typ,1,1, tmpfile);fclose(tmpfile);if(typ=='d'){fprintf(stdout,"文件夹\n");}else{fprintf(stdout,"文件\n");}remove(tmp);return0;}

  如果想把脚本直接放到C代码里也可以这样写:

#include#include#includechar bash_script_data[4096];char*browse_dir(constchar*init_dir,constchar*output){strcpy(bash_script_data,"#!/bin/bash\n""ERROR_CD=1\n""ENTER_LABEL=\"选择文件/进入文件夹\"\n""DONE_LABEL=\"选择当前文件夹\"\n""TITLE=\"浏览\"\n""TIP=\"当前路径: \"\n""savedir=$(pwd)\n""tmpfile=$(mktemp)\n""function show()\n""{\n""	local init_dir=$(realpath \"$1\")\n""	if ! cd \"$init_dir\"; then\n""		return $ERROR_CD\n""	fi\n""	local list=$(ls -aQ)\n""	local old_IFS=$IFS\n""	IFS=$'\\n'\n""	listarr=($list)\n""	IFS=$old_IFS\n""	list=''\n""	for i in ${!listarr[*]}; do\n""		list=\"$list ${listarr[$i]} \\\"$(eval \"date -d @\\$(stat ${listarr[$i]} -c %Y) '+%Y-%m-%d %T'\")    $(eval \"stat ${listarr[$i]} -c %F\")\\\"\"\n""	done\n""	eval \"dialog --ok-label '$ENTER_LABEL' --cancel-label '$DONE_LABEL' --title '$TITLE' --menu '${TIP}${init_dir}' 0 0 0 $list 2>'$tmpfile'\"\n""	return 0\n""}\n""function next_action()\n""{\n""	local item=$1\n""	if [ \"$item\" == \"\" ]; then\n""		echo \"$(pwd)\" >\"$tmpfile\"\n""		return 0\n""	fi\n""	local typ=$(ls -ld \"$item\" | cut -c 1)\n""	if [ \"$typ\" == \"d\" ]; then\n""		browse_dir \"$item\"\n""	elif [ \"$typ\" == \"l\" ]; then\n""		local lnk=$(readlink \"$item\")\n""		if ! cd \"$(dirname \"$lnk\")\"; then\n""			return $ERROR_CD\n""		fi\n""		next_action \"$(basename \"$lnk\")\"\n""	else\n""		echo \"$(realpath \"$item\")\" >\"$tmpfile\"\n""	fi\n""}\n""function browse_dir()\n""{\n""	local status\n""	local init_dir=$1\n""	show \"$init_dir\"\n""	status=$?\n""	if [ $status -ne 0 ]; then\n""		return $status\n""	fi\n""	local item=$(cat \"$tmpfile\")\n""	next_action \"$item\"\n""}\n""INIT_DIR=");strcat(bash_script_data, init_dir);strcat(bash_script_data,"\n""browse_dir \"$INIT_DIR\"\n""status=$?\n""if [ $status -ne 0 ]; then\n""	exit $status\n""fi\n""result=$(cat \"$tmpfile\")\n""rm -f \"$tmpfile\"\n""cd \"$savedir\"\n""echo \"$result\" >");strcat(bash_script_data, output);strcat(bash_script_data,"\n");return bash_script_data;}intmain(){char tmp[11]="tmp.XXXXXX";char cmd[512]={0};char item[261]={0};char typ;
	FILE*tmpfile=NULL;int tmpfd=mkstemp(tmp);close(tmpfd);system(browse_dir("/", tmp));
	tmpfile=fopen(tmp,"rb");fread(item,260,1, tmpfile);fclose(tmpfile);strtok(item,"\n");fprintf(stdout,"你选择了: %s\n", item);fprintf(stdout,"它是一个: ");sprintf(cmd,"ls -ld %s | cut -c 1 >%s", item, tmp);system(cmd);
	tmpfile=fopen(tmp,"rb");fread(&typ,1,1, tmpfile);fclose(tmpfile);if(typ=='d'){fprintf(stdout,"文件夹\n");}else{fprintf(stdout,"文件\n");}remove(tmp);return0;}

  输出:
在这里插入图片描述


推荐阅读
  • 驱动程序的基本结构1、Windows驱动程序中重要的数据结构1.1、驱动对象(DRIVER_OBJECT)每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱 ... [详细]
  • 关于进程的复习:#管道#数据的共享Managerdictlist#进程池#cpu个数1#retmap(func,iterable)#异步自带close和join#所有 ... [详细]
  • 整理于2020年10月下旬:总结过去,展望未来Itistoughtodayandtomorrowwillbetougher.butthedayaftertomorrowisbeau ... [详细]
  • 本文探讨了SSD购买后是否需要进行4K对齐的问题,并详细解释了4K对齐的原理及其重要性。通过对比机械硬盘与固态硬盘的结构,文章深入分析了4K对齐对SSD性能的影响,并提供了具体的对齐方法。 ... [详细]
  • 在项目需要国际化处理时,即支持多种语言切换的功能,通常有两种方案:单个包和多个包。本文将重点讨论单个包的实现方法。 ... [详细]
  • 阿里云 Aliplayer高级功能介绍(八):安全播放
    如何保障视频内容的安全,不被盗链、非法下载和传播,阿里云视频点播已经有一套完善的机 ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • vsftpd配置(虚拟用户、匿名用户登录)
    一、ftp服务搭建(一)概述1.ftp连接及传输模式(1)控制连接TCP21,用于发送FTP命令信息 ... [详细]
  • vue引入echarts地图的四种方式
    一、vue中引入echart1、安装echarts:npminstallecharts--save2、在main.js文件中引入echarts实例:  Vue.prototype.$echartsecharts3、在需要用到echart图形的vue文件中引入:   importechartsfrom&amp;quot;echarts&amp;quot;;4、如果用到map(地图),还 ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 申请地址:https://developer.apple.com/appstore/contact/?topic=expedite 常见申请理由:1. 我们即将发布新产品,这是一个媒体活动,我们无法承担任何风险,因此在多个方面努力提升应用质量。 ... [详细]
  • 使用 Mui.js 获取复选框值的方法
    本文介绍如何使用 Mui.js 框架来获取复选框的值,并通过数组进行处理和展示。 ... [详细]
  • MySQL 5.7 服务端在 Windows 上的安装与配置
    本文详细介绍了在 Windows 系统上安装和配置 MySQL 5.7 服务端的方法,包括 my.ini 配置文件的设置、初始化数据库、启动服务以及设置用户权限等步骤。 ... [详细]
author-avatar
手机用户2502880821
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有