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

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


推荐阅读
  • WinSCP: 跨Windows与Linux系统的高效文件传输解决方案
    本文详细介绍了一款名为WinSCP的开源图形化SFTP客户端,该工具支持SSH协议,适用于Windows操作系统,能够实现与Linux系统之间的文件传输。对于从事嵌入式开发的技术人员来说,掌握WinSCP的使用方法将极大提高工作效率。 ... [详细]
  • Ubuntu GamePack:专为游戏爱好者打造的Linux发行版
    随着Linux系统在游戏领域的应用越来越广泛,许多Linux用户开始寻求在自己的系统上畅玩游戏的方法。UALinux,一家致力于推广GNU/Linux使用的乌克兰公司,推出了基于Ubuntu 16.04的Ubuntu GamePack,旨在为Linux用户提供一个游戏友好型的操作环境。 ... [详细]
  • 利用SSH隧道实现外网对局域网机器的安全访问
    本文探讨了一种常见的网络配置问题及其解决方案,即如何在外网环境下安全地访问位于局域网内的计算机。特别介绍了使用SSH反向隧道技术来实现这一目标的具体步骤和注意事项。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 在Linux系统上构建Web服务器的详细步骤
    本文详细介绍了如何在Linux系统上搭建Web服务器的过程,包括安装Apache、PHP和MySQL等关键组件,以及遇到的一些常见问题及其解决方案。 ... [详细]
  • iTOP4412开发板QtE5.7源码编译指南
    本文详细介绍了如何在iTOP4412开发板上编译QtE5.7源码,包括所需文件的位置、编译器设置、触摸库编译以及QtE5.7的完整编译流程。 ... [详细]
  • Linux环境下Git安装及常见问题解析
    本文详细介绍了在Ubuntu系统中安装Git的过程,包括环境检查、软件安装、用户配置以及SSH密钥生成等步骤,并针对安装过程中可能出现的问题提供了有效的解决方案。 ... [详细]
  • 本文详细介绍了Linux操作系统中的cp和scp命令,包括它们的基本使用方法、常见选项以及如何通过scp命令安全地在不同主机之间传输文件。 ... [详细]
  • Python编码入门指南
    本文探讨了使用Python进行网络设备连通性测试的简便性,特别是针对IP地址范围为192.168.0.101至192.168.0.200的设备。通过比较Python与Shell、Java等语言,展示了Python在执行此类任务时的优势。 ... [详细]
  • 本文档详细介绍了在 Kubernetes 集群中部署 ETCD 数据库的过程,包括实验环境的准备、ETCD 证书的生成及配置、以及集群的启动与健康检查等关键步骤。 ... [详细]
  • 本文探讨了如何使用ls -lsh命令排除总大小输出,仅显示文件大小的方法,并提供了几种实现这一目标的解决方案。 ... [详细]
  • 在Ubuntu 16.04中使用Anaconda安装TensorFlow
    本文详细介绍了如何在Ubuntu 16.04系统上通过Anaconda环境管理工具安装TensorFlow。首先,需要下载并安装Anaconda,然后配置环境变量以确保系统能够识别Anaconda命令。接着,创建一个特定的Python环境用于安装TensorFlow,并通过指定的镜像源加速安装过程。最后,通过一个简单的线性回归示例验证TensorFlow的安装是否成功。 ... [详细]
  • 如何创建个性化Ubuntu Live CD
    随着Ubuntu频繁的版本更新,越来越多的用户开始探索创建个性化Ubuntu Live CD的方法。这不仅能满足特定的硬件和软件需求,还能极大地提升用户体验。本文将详细介绍使用Distroshare Ubuntu Imager创建定制化Ubuntu Live CD的过程。 ... [详细]
  • 本文探讨了在Git子模块目录中运行pre-commit时遇到的错误,并提供了一种通过Docker环境解决此问题的方法。 ... [详细]
  • 本文详细介绍了如何在Linux系统中安装和配置GitLab Runner,包括添加YUM源、安装GitLab Runner以及注册Runner的具体步骤。 ... [详细]
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社区 版权所有