Вот bash -центральная версия; он опирается на следующие функции bash:
**/
cdd() {
local _cdd_unset_globstar=0
shopt -q globstar || _cdd_unset_globstar=1
shopt -s globstar
local _cdd_deepest=$1
local _cdd_level=1
local _cdd_array=()
for d in "${1}/"**/
do
IFS=/ read -r -d '' -a _cdd_array <<< "$d" || true
if [ "${#_cdd_array[*]}" -gt "$_cdd_level" ]
then
_cdd_deepest=$d
_cdd_level=${#_cdd_array[*]}
fi
done
cd -- "$_cdd_deepest" && true
local _cdd_ret="$?"
[ "$_cdd_unset_globstar" -eq 1 ] && shopt -u globstar
return "$_cdd_ret"
}
Функция выполняет следующие действия:
$1
и 1
соответственно ). /
; подсчитайте количество элементов в массиве и сравните его с известным в настоящее время -самым глубоким уровнем каталога. Если это глубже, сбросьте эти переменные. cd
в него. Если вам кажется более правильным использовать подоболочку для установки опций оболочки, то вы можете подойти к этому с помощью двух функций :оболочки и подоболочки -, вызывающей функцию, которая делает вышеописанное:
cdd_helper() (
shopt -s globstar
_cdd_deepest=$1
_cdd_level=1
for d in "${1}/"**/
do
IFS=/ read -r -d '' -a _cdd_array <<< "$d" || true
if [ "${#_cdd_array[*]}" -gt "$_cdd_level" ]
then
_cdd_deepest=$d
_cdd_level=${#_cdd_array[*]}
fi
done
printf "%s" "$_cdd_deepest"
)
cdd() {
cd -- "$(cdd_helper "$1")"
}
Вы немного ошиблись в своих предположениях. Блокировать специальные файлы — это такие вещи, как раздел жесткого диска, устройства памяти. Например, основной раздел моего жесткого диска -— /dev/sda1
. Тестовый флаг (или[
)-b
будет работать для этого, но он не будет работать для файла изображения, который считается обычным файлом.
$ test -b./Pictures/NOTEBOOKS/8.jpg && echo "It's a block device" || echo "Not a block device"
Not a block device
$ test -b /dev/sda1 && echo "It's a block device" || echo "Not a block device"
It's a block device
Символьные устройства — это такие вещи, как tty и последовательные консоли. Например:
$ test -c /dev/tty1 && echo "It's a character device" || echo "Not a character dev"
It's a character device
И stat
может сообщить вам практически ту же информацию, только в текстовой форме вместо статуса выхода, как это делает test
:
$ stat --printf "%n\t%F\n" /dev/tty1 /dev/sda1./mytext.txt./Pictures/NOTEBOOKS/8.jpg
/dev/tty1 character special file
/dev/sda1 block special file
./mytext.txt regular file
./Pictures/NOTEBOOKS/8.jpg regular file
Вам следует использовать команду file
и проверить ее вывод:
$ file./Pictures/NOTEBOOKS/8.jpg
./Pictures/NOTEBOOKS/8.jpg: JPEG image data, JFIF standard 1.02, aspect ratio, density 100x100, segment length 16, baseline, precision 8, 750x750, frames 3
$ file /dev/sda1
/dev/sda1: block special (8/1)
$ file mytext.txt
mytext.txt: ASCII text
$ cat test-c.bash
#! /bin/bash
echo -e "Enter file name: \c"
read file_name
if [ -c $file_name ]
then
echo Character special file $file_name found
else
echo Character special file $file_name not found
fi
$ bash test-c.bash
Enter file name: /dev/tty
Character special file /dev/tty found
$ cat test-b.bash
#! /bin/bash
echo -e "Enter file name: \c"
read file_name
if [ -b $file_name ]
then
echo Block special file $file_name found
else
echo Block special file $file_name not found
fi
$ bash test-b.bash
Enter file name: /dev/sda
Block special file /dev/sda found
За исключением отсутствующего fi
в ваших программах, они делают то, что и следовало ожидать.
Ваше предположение...
test.txt is a character special file
img.jpg is a block special file
...вероятно, это неправильно, если вы не создали их для выполнения этого, например. используя mknod
.
(См. man mknod
.)
Таким образом, если ваши тестовые файлы соответствуют названиям, то это просто обычные (обычные )файлы.
Что вы искали?
Способ различать текстовые файлы и двоичные файлы, как в операционных системах DOS?
Это реликт времен CP/M или даже старше. Файловая система действительно отслеживала размеры файлов в блоках, и поэтому текстовые файлы нуждались в символе конца файла, чтобы пометить конец действительного текста.
Следствием этого является то, что объединение двоичных файлов и текстовых файлов должно выполняться по-разному.
Файловые системы Unix отслеживают размер файла в блоках и в фактически используемых байтах, поэтому нет необходимости помечать конец текста с помощью специального символа окончания.
Если вы хотите угадать, что находится внутри файла, вы можете использовать команду file
:
$ file 20170130-094911-GMT.png
20170130-094911-GMT.png: PNG image data, 744 x 418, 8-bit/color RGBA, non-interlaced
$ file calendar.txt
calendar.txt: ASCII text
ХТХ!