Скрипт для просмотра папок $PATH и поиска исполняемых файлов в вашей системе

С awk :

awk -F/ '$1=="<<" {i=$2; for(j=3;j<=NF;j++) \
         if($j~/^Contents/) split($j,a,"[()]"); print i " _ " a[2]}' file.txt
  • Установка разделителя полей как / , если первое поле ] << , затем сохранение второго поля как переменной i для печати позже

  • Итерация по остальным полям, и если какое-либо поле начинается с Contents , то разделение поля на () для создания массива a , для (j = 3; j <= NF; j ++) if ($ j ~ / ^ Contents /) split ($ j, a, "[()]")

  • выводит переменную i и второй элемент массива a , разделяя их _

Пример:

% cat file.txt                                                                                                        
1731 0 obj
<</Page 250/Type/Annot/Subtype/Highlight/Rotate 0/Rect[ 95.4715 347.644 337.068 362.041]/NM(929cd95c-f962-4fa3-b734-2e0e67d7b321)/T(iPad)/CreationDate(D:20160818145053Z00'00')/M(D:20160818145204Z00'00')/C[ 0.454902 0.501961 0.988235]/CA 1/QuadPoints[ 95.4715 362.041 337.068 362.041 95.4715 347.644 337.068 347.644]/Contents(EXAMPLE OF TEXT TO BE EXTRACTED)/F 4/Subj(Highlight)>>
endobj

% awk -F/ '$1=="<<" {i=$2; for(j=3;j<=NF;j++) if($j~/^Contents/) split($j,a,"[()]"); print i " _ " a[2]}' file.txt
Page 250 _ EXAMPLE OF TEXT TO BE EXTRACTED
2
07.04.2017, 02:42
5 ответов
#!/bin/bash

OLD_IFS=${IFS}
IFS=:

for folder in $PATH
do
        cd ${folder}
        echo "Inside the folder ${folder}"
        for file in *
        do
             if [ -x ${file} ]
             then
                  echo "${file} is executable"
             else
                  echo "${file} is not executable"
             fi
         done
done
IFS=${OLD_IFS}
0
27.01.2020, 21:48

С одной стороны, $ PATH дает список каталогов. Если вы хотите проверить каждый файл в $ PATH , вам нужно будет просмотреть каждый файл в каждом каталоге, а не просто проверять каждый элемент в $ PATH .

Затем вы используете -x , чтобы проверить, является ли файл исполняемым, но вы не указываете, какой файл проверять. Я написал исправленную версию ниже:

IFS=':'
for directory in $PATH; do
    for file in $directory/*; do
        if [ -x $file ]; then
            echo "Executable File: " $file
        else
            echo "Not executable: " $file
        fi
    done
done

Ответ Фокса - гораздо более хорошее решение, но я просто подумал, что вам будет интересно узнать, что не так с вашим.

7
27.01.2020, 21:48

Если вам нужен список исполняемых файлов, find будет достаточно:

IFS=':'
find $PATH -type f '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')'

Это перечислит полный путь каждого исполняемого файла в ваш $ PATH . IFS = ':' обеспечивает разделение $ PATH на двоеточия (: ), разделитель для этой переменной.

Если вам не нужен полный путь , а только имена исполняемых файлов , вы можете сделать

IFS=':'
find $PATH -type f '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')' -exec basename {} \; | sort

Если ваш find совместим с GNU , условие немного упрощается:

IFS=':'
find $PATH -type f -executable -exec basename {} \; | sort

Как указывает @StephenHarris, с этим есть небольшая проблема: если есть подкаталоги вашего $ PATH , файлы в этих подкаталогах могут быть зарегистрированы даже хотя $ PATH не может связаться с ними. Чтобы обойти это, вам на самом деле понадобится find с большим количеством параметров, чем требует POSIX.GNU-совместимый может обойти это с помощью:

IFS=':'
find $PATH -maxdepth 1 -type f -executable -exec basename {} \; | sort

-maxdepth 1 сообщает find не входить ни в один из этих подкаталогов.

8
27.01.2020, 21:48
IFS=:; set -f;
find -- $PATH -type d -prune -exec sh -c '
cd "$1" && \
find . -type d ! -name . -prune \
           -o \
-type f \( -perm -u+x -o -perm -g+x -o -perm -o+x \) -exec echo Executable File: \{\} \; \
           -o \
-type f  ! -perm -u+x  ! -perm -g+x  ! -perm -o+x    -exec echo Not executable: \{\} \;
' {} {} \;

IFS установлен на двоеточие, разделитель PATH, и сопоставление glob также заблокировано, чтобы исключить любое разделение на символы glob в именах, найденных в PATH.

Затем $PATH разделяется и представляется в качестве ведущих аргументов для find до получения любых опций. Мы выбираем только те аргументы из них, которые являются каталогами. (Если мы хотим получить ссылки и на dir, то задайте опцию -L). А затем мы просто ныряем до первого уровня в этих каталогах и выхватываем те файлы, которые являются исполняемыми кем-то (т.е. кем-то из пользователей/групп/других)

.
0
27.01.2020, 21:48

Специально для bash вы можете воспользоваться встроенным модулем compgen:

  • compgen -c перечисляет все доступные команды, встроенные модули, функции, псевдонимы и т.д. (по сути, все, что может появиться, если нажать Tab в пустом приглашении).
  • compgen -b перечисляет все встроенные модули, аналогично d для каталогов, f для файлов, a для псевдонимов и так далее.

Так что вы можете использовать вывод compgen и злоупотреблять which:

$ compgen -c | xargs which -a
/bin/egrep
/bin/fgrep
/bin/grep
/bin/ls
/bin/ping
/usr/bin/time
/usr/bin/[
/bin/echo
/bin/false
/bin/kill

Первые пять - это фактически псевдонимы, затеняющие команды в моем случае, затем у нас есть ключевые слова и встроенные модули, так что, похоже, есть некоторый порядок в выводе compgen.

4
27.01.2020, 21:48

Теги

Похожие вопросы