将文件转换为目录

我们知道“Linux中的一切”是一个文件,而且目录只是一个包含其他文件的文件。

所以,我不知道这个“疯狂的想法”是否可行,但它应该是根据上述原则进行的。

简单来说,我怎么能将现有的空文件更改为目录。 可能吗?

作为一些脑风暴我想文件元数据的一些修改,并使其作为目录元数据应该成功!

任何信息表示赞赏。


更新:我肯定不想删除文件并创建目录! 我只想知道如果你可以使用一些文件元数据,上面的哲学适用多少。

创建测试Ext4文件系统:

  1. 首先在受控文件上创建一个文件系统,以避免破坏您的真实文件系统:

    dd if=/dev/zero of=test_fs bs=10M count=1 

    这将创建一个名为test_fs的文件,大小为10兆字节。

  2. 然后在其上创建一个Ext4文件系统:

     mkfs.ext4 test_fs 

放一些文件:

  1. 我们有一个function齐全的文件系统。 让我们装载它:

     sudo mount test_fs /mnt 
  2. 让我们创建一个文件夹和一个文件。

     sudo mkdir /mnt/folder echo "Foo" | 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. 使用写权限( -w标志)对test_fs运行debugfs

     debugfs -w test_fs 
  2. file转换为文件夹:

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

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

       040644 
    • 继续按Return键以保留剩余数据,直到再次出现提示。

  3. folder转换为文件:

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

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

       0100644 
    • 继续按Return键以保留剩余数据,直到再次出现提示。

  4. 要退出debugfs提示符,只需按q然后返回


检查一切是否顺利:

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

     sudo mount test_fs /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 prmissions. 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 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 when ^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 # While Linux is Open Source: ## 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 it's 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 # End if. ## 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 a space). declare $var="${!var// /-}" # Convert spaces to hyphens. if [[ "$var" == "type" ]]; then # If the current variable is type: declare $var="${!var//-/f}" # Convert hyphen to f. fi # End if. 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 is 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。