将文件转换为目录

Maythux

众所周知,“ Linux中的所有内容”都是文件,而且目录仅是包含其他文件的文件。

因此,我不知道这种“疯狂的想法”是否可行,但应该以上述原则为依据。

简单来说,如何将现有的空文件更改为目录。是否有可能?

由于有些头脑风暴,我想对文件元数据进行一些修改,使其成为目录元数据就可以了!

任何信息表示赞赏。


更新:确定我不想删除文件而是创建目录!我只是想知道如果您可以使用某些文件元数据,那么上述原理在多大程度上适用。

0x2b3bfa0

实现转化

创建一个测试文件系统

为了保护我们的主文件系统不受任何可能的破坏,在运行此实验后,我们将在普通文件内创建一个小的文件系统以进行测试。

  1. 创建一个名为0的零填充文件test,大小为10 MB:

    dd if=/dev/zero of=~/test bs=10M count=1
    
  2. 在文件内部创建一个Ext4文件系统,就好像它是一个分区一样:

    mkfs.ext4 ~/test
    

创建一些文件和目录

现在我们在test文件中拥有一个功能齐全的文件系统,因此我们将在其中创建一些文件和目录。

  1. 将新创建的文件系统挂载到内/mnt

    sudo mount ~/test /mnt
    
  2. 创建一个文件和一个目录:

    sudo mkdir /mnt/folder
    echo "contents" | sudo tee /mnt/file
    
  3. 检查文件系统的内容:

    ls -l /mnt
    

    输出应该是这样的:

    total 2
    -rw-r--r-- 1 root root     0 may 21 18:53 file
    drw-r--r-- 2 root root  1024 may 21 18:55 folder
    
  4. 卸载测试文件系统:

    sudo umount /mnt
    

交换文件和文件夹

  1. 运行debugfstest具有写权限(文件-w标志):

    debugfs -w ~/test
    
  2. 转换file为文件夹:

    • debugfs提示符下,键入以下内容:

      modify_inode file
      
    • 将会出现一个提示,询问您一种模式。输入:

      040644
      
    • 持续按return可以保留其余数据,直到再次出现提示。

  3. 转换folder成文件:

    • debugfs提示符下,键入以下内容:

      modify_inode folder
      
    • 将会出现一个提示,询问您一种模式。输入:

      0100644
      
    • 持续按return可以保留其余数据,直到再次出现提示。

  4. 要退出debugfs提示,只需点击q然后return

检查操作是否成功

  1. 再次挂载测试文件系统:

    sudo mount ~/test /mnt
    
  2. 检查文件系统内容:

    ls -l /mnt
    

    现在,它应该像显示目录一样显示文件,反之亦然

    total 2
    drw-r--r-- 1 root root     0 may 21 18:53 file
    -rw-r--r-- 2 root root  1024 may 21 18:55 folder
    

用于计算inode模式的脚本

#!/bin/bash

#### See https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Inode_Table

## Terminal measures:
x="$(( $(tput cols) / 2 ))"   # Width of the terminal
y="$(( $(tput lines) /  2 ))" # Height of the terminal

## File descriptors:
declare -A types       # Declare an associative array with file descriptors
types[f]='0x8000'      # File
types[l]='0xA000'      # Link
types[s]='0xC000'      # Socket
types[d]='0x4000'      # Directory
types[p]='0x1000'      # Named pipe
types[b]='0x6000'      # Block device
types[c]='0x2000'      # Character device

## Permissions:
declare -A permission  # Declare an associative array with permissions
permission[user_S]='0x800'  # UID
permission[user_s]='0x840'  # UID and user can execute
permission[user_r]='0x100'  # User can read
permission[user_w]='0x80'   # User can write
permission[user_x]='0x40'   # User can execute
permission[group_S]='0x400' # GID
permission[group_s]='0x408' # GID and group can execute
permission[group_r]='0x20'  # Group can read
permission[group_w]='0x10'  # Group can write
permission[group_x]='0x8'   # Group can execute
permission[other_T]='0x200' # Sticky bit
permission[other_t]='0x201' # Sticky bit and other can execute
permission[other_r]='0x4'   # Other can read
permission[other_w]='0x2'   # Other can write
permission[other_x]='0x1'   # Other can execute

## Cleanup function:
function cleanup() {
    tput cvvis        # Make the cursor visible
    tput rmcup        # Restore saved terminal contents
    stty sane         # Fix problems caused by read -s
    exit 0            # Exit gracefully
}

## Function to print at a specified position:
function pprint() {
    tput cup $1 $2
    printf "${@:3}"
}

## Function to clear the notification area:
function reset() {
    pprint $((y+2)) $((x-40)) ' %.0s' {1..25} # Print 25 spaces
}

## Function to notify something to the user:
function notify() {
    reset                          # Clear the notification area
    pprint $((y+2)) $((x-40)) "$@" # Print the notification text
}

## If the terminal is smaller than 100x8, exit gracefully (self-explainatory):
if [ $x -lt 50 ] || [ $y -lt 5 ]; then
    echo 'Error, I need a minimum of 100x10 lines to run'
    exit 0
fi

## Initialize the terminal:
trap cleanup EXIT SIGHUP SIGINT SIGTERM # Call cleanup function after receiving ^C
stty -echo  cbreak                      # Put terminal in silent mode
tput smcup                              # Save terminal contents
tput civis                              # Make the cursor inisible

## Draw the big box:
printf '\033[1;37m'                            # Color
pprint $((y-3)) $((x-48)) '\u2500%.0s' {1..97} # Upper line
pprint $((y+4)) $((x-48)) '\u2500%.0s' {1..97} # Lower line
for ((i=4;i>-4;i--)); do                       # Sides:
    pprint $((y+i)) $((x-49)) '\u2502'             # Left line
    pprint $((y+i)) $((x+49)) '\u2502'             # Right line
done                                           # End sides
pprint $((y-3)) $((x-49)) '\u256D'             # Upper-left corner
pprint $((y+4)) $((x-49)) '\u2570'             # Lower-left corner
pprint $((y-3)) $((x+49)) '\u256E'             # Upper-right corner
pprint $((y+4)) $((x+49)) '\u256F'             # Lower-right corner

## Draw the small box:
printf '\033[1;35m'                             # Color
pprint $((y+1)) $((x-10)) '\u2501%.0s' {1..10}  # Upper line
pprint $((y+3)) $((x-10)) '\u2501%.0s' {1..10}  # Lower line
pprint $((y+2)) $((x-11)) '\u2503'              # Left line
pprint $((y+2)) $((x+00)) '\u2503'              # Right line
pprint $((y+1)) $((x-11)) '\u250F'              # Upper-left corner
pprint $((y+3)) $((x-11)) '\u2517'              # Lower-left corner
pprint $((y+1)) $((x+00)) '\u2513'              # Upper-right corner
pprint $((y+3)) $((x+00)) '\u251B'              # Lower-right corner

## Print type help:
pprint $((y-2)) $((x-44)) '\033[0;37mInode type: \033[1;37mf\033[0;37mile, \033[1;37md\033[0;37mirectory, \033[1;37ml\033[0;37mink, named \033[1;37mp\033[0;37mipe, \033[1;37ms\033[0;37mocket, \033[1;37mc\033[0;37mharacter device or \033[1;37mb\033[0;37mlock device.'

## Print permission help:
pprint $((y-1)) $((x-40)) '\033[0;36mPermission (\033[1;32mu\033[0;32mser\033[0;36m, \033[1;33mg\033[0;33mroup\033[0;36m or \033[1;31mo\033[0;31mther\033[0;36m): \033[1;36mr\033[0;36mead, \033[1;36mw\033[0;36mrite, e\033[1;36mx\033[0;36mecute, \033[1;36mhyphen\033[0;36m or \033[1;36mspace\033[0;36m to skip.'
pprint $((y+0)) $((x+8)) 's\033[1;36mt\033[0;36micky bit and executable, '
pprint $((y+1)) $((x+8)) 's\033[1;36mT\033[0;36micky bit not executable, '
pprint $((y+2)) $((x+8)) '\033[1;36ms\033[0;36metuid/setgid and executable, '
pprint $((y+3)) $((x+8)) '\033[1;36mS\033[0;36metuid/setgid not executable. '

## Endless loop:
while :; do

    ## Clear the input area:
    pprint $((y+2)) $((x-10)) '% *s\n' 10         # Print 16 spaces

    ## Print mask in the input area:
    printf '\033[1;37m'                           # Color for the type
    pprint $((y+2)) $((x-10)) '\u2588'            # Block for the type
    printf '\033[1;36m'                           # Color for the permision
    pprint $((y+2)) $((x- 9)) '\u2588%.0s' {1..9} # Blocks for the permission

    ## Loop through all variables to make a proper input:
    for var in type {user,group,other}_{r,w,x}; do

        ## Assign colors and regex to fields:
        case "$var" in
            (type)    color='\033[1;37m';     regex='^[fdlpscb]$'    ;;

            (other_x)                         regex='^[-xtT]$'       ;;&
            (user_x|group_x)                  regex='^[-xsS]$'       ;;&
            (user_[rw]|group_[rw]|other_[rw]) regex="^[-${var: -1}]$";;&

            (user*)   color='\033[1;32m'                             ;;
            (group*)  color='\033[1;33m'                             ;;
            (other*)  color='\033[1;31m'                             ;;
        esac

        ## Change the pointer position:
        pprint $((y+3)) $(((x-10)+pointer)) "${color}\u2501"           # Print the pointer on its new position
        if (( pointer > 0 )); then                                     # If the pointer is not in the first position:
            pprint $((y+3)) $(((x-10)+(pointer-1))) '\033[1;35m\u2501'     # Clear the old pointer         
        fi

        ## Infinite loop until there is a valid input for the current character:
        while :; do
            printf "$color"                       # Set the character color
            IFS= read -rn 1 $var                  # Read a character (even if it's a space)

            declare $var="${!var// /-}"           # Convert spaces to hyphens.
            if [[ "$var" == "type" ]]; then       # If the current variable is type:
                declare $var="${!var//-/f}"           # Convert "-" to "f"
            fi

            if [[ "${!var}"  =~ $regex ]]; then   # If there is a valid input:
                reset                                 # Clear error notification if any
                break                                 # Exit from this loop
            else                                  # Else:
                notify "\033[1;31mWrong input!"       # Print the error message
            fi
        done

        ## Print the entered value:
        pprint $((y+2)) $(((x-10)+pointer)) "${!var}"

        ## Sum the current permission:
        ((mode+=permission[${var%_*}_${!var}]))

        ## Increment the pointer:
        ((pointer++))
    done

    ## Post-read:
    unset pointer                                 # Reset the pointer
    pprint $((y+3)) $((x-1)) "\033[1;35m\u2501"   # Clear the pointer
    read -n 1                                     # Wait for Return or another character

    ## Sum file descriptor type:
    ((mode+=${types[$type]}))

    ## Final commands:
    mode=$(printf "%o" $mode)                      # Convert mode to octal (before this was decimal)
    notify "\033[1;32mOctal mode:\033[1;34m $mode" # Print the octal mode
    unset mode                                     # Reset the mode
done

在GitHub上查看脚本

障碍

  • 该文件夹无法打开。除非您将原来包含它的“原始文件夹数据”放在上面否则您将无法打开它

进一步阅读

https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Inode_Table


感谢@tallus他给了我一个很好的提示:

debugfs具有Modify_inode命令,该命令使您可以直接编辑inode,这将使您可以将文件标志设置为dir。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将目录转换为文件或将文件转换为目录

将文件系统中的目录结构转换为 Json 对象

将文件或目录转换为符号链接并保留权限

将视频转换为新的文件夹结构时,“没有此类文件或目录”

如何将目录的所有json文件转换为python中的文本文件?

在Windows中使用Ghostscript将多个PDF文件转换为子目录中的Text文件

批处理文件将目录中的所有文件转换为ATF

使用嵌套目录将文件名转换为完整目录路径的优化方法,用于大文件存储

如何将目录转换为ZIP?

将文件转换为字典

将文件转换为CSV

将BufferedReader转换为文件

将BytesIO转换为文件

将位图转换为文件

将IFile转换为文件

将文件转换为字典

通过VBA将目录中的所有XML文件转换为XLS

Uncompyle6将pyc转换为py文件python 3(整个目录)

如何将Scala目录(文件,路径)转换为Java java.io.File

如何使用Pug将Markdown文件目录转换为HTML页面?

使用Node.js将文件系统中的目录结构转换为JSON

如何将制表符转换为目录的每个文件中的空格?

将DVD VIDEO_TS目录转换为单个mp4或mkv文件?

使用 pandoc 将 epub/pdf(和其他文本文件)的目录转换为 .txt

将Unix目录中的所有文件转换为另一种格式

将特定目录中的所有文件转换为xml(批处理)

将目录中的文件列表转换为列表,以便可以被发送-python

将多个目录的CSV文件转换为PySpark中的实木复合地板

如何将子文件夹的目录从 FLAC 批量转换为 ALAC?