热门标签 | 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;}

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


推荐阅读
  • 本文详细记录了在银河麒麟操作系统和龙芯架构上使用 Qt 5.15.2 进行项目打包时遇到的问题及解决方案,特别关注于 linuxdeployqt 工具的应用。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • CentOS系统安装与配置常见问题及解决方案
    本文详细介绍了在CentOS系统安装过程中遇到的常见问题及其解决方案,包括Vi编辑器的操作、图形界面的安装、网络连接故障排除等。通过本文,读者可以更好地理解和解决这些常见问题。 ... [详细]
  • 嵌入式开发环境搭建与文件传输指南
    本文详细介绍了如何为嵌入式应用开发搭建必要的软硬件环境,并提供了通过串口和网线两种方式将文件传输到开发板的具体步骤。适合Linux开发初学者参考。 ... [详细]
  • Symfony是一个功能强大的PHP框架,以其依赖注入(DI)特性著称。许多流行的PHP框架如Drupal和Laravel的核心组件都基于Symfony构建。本文将详细介绍Symfony的安装方法及其基本使用。 ... [详细]
  • 本文详细介绍了如何在云服务器上配置Nginx、Tomcat、JDK和MySQL。涵盖从下载、安装到配置的完整步骤,帮助读者快速搭建Java Web开发环境。 ... [详细]
  • 本文详细记录了在基于Debian的Deepin 20操作系统上安装MySQL 5.7的具体步骤,包括软件包的选择、依赖项的处理及远程访问权限的配置。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文介绍如何通过SSH协议使用Xshell远程连接到Ubuntu系统。为了实现这一目标,需要确保Ubuntu系统已安装并配置好SSH服务器,并保证网络连通性。 ... [详细]
  • 在创建新的Android项目时,您可能会遇到aapt错误,提示无法打开libstdc++.so.6共享对象文件。本文将探讨该问题的原因及解决方案。 ... [详细]
  • 本文将详细介绍如何在没有显示器的情况下,使用Raspberry Pi Imager为树莓派4B安装操作系统,并进行基本配置,包括设置SSH、WiFi连接以及更新软件源。 ... [详细]
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社区 版权所有