Используйте PyGame, чтобы иметь окно, а затем вы можете получить ключевые события.
Для буквы p
:
import pygame, sys
import pygame.locals
pygame.init()
BLACK = (0,0,0)
WIDTH = 1280
HEIGHT = 1024
windowSurface = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)
windowSurface.fill(BLACK)
while True:
for event in pygame.event.get():
if event.key == pygame.K_p:
#Do what you want to here
pass
if event.type == pygame.locals.QUIT:
pygame.quit()
sys.exit()
Чтобы проверить, существует ли каталог в скрипте оболочки, вы можете использовать следующее:
if [ -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY exists.
fi
Или проверить, существует ли каталог:
if [ ! -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY doesn't exist.
fi
Однако, как указывает Jon Ericson , последующие команды могут не работать должным образом, если вы не принимаете во внимание, что символическая ссылка на каталог также пройдет эту проверку. Например. запускать это:
ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then
rmdir "$SYMLINK"
fi
Вызвать сообщение об ошибке:
rmdir: failed to remove `symlink': Not a directory
Таким образом, возможно, что символьные ссылки обрабатываются по-разному, если последующие команды ожидают каталоги:
if [ -d "$LINK_OR_DIR" ]; then
if [ -L "$LINK_OR_DIR" ]; then
# It is a symlink!
# Symbolic link specific commands go here.
rm "$LINK_OR_DIR"
else
# It's a directory!
# Directory command goes here.
rmdir "$LINK_OR_DIR"
fi
fi
Особо обратите внимание на двойные кавычки, используемые для обертывания переменных, причина этого объясняется 8jean в другом ответе .
Если переменные содержат пробелы или другие необычные символы, вероятно, это приведет к сбою сценария.
Согласно комментарий Jonathan :
Если вы хотите создать каталог, и он еще не существует, то самым простым методом является использование mkdir -p
, который создает каталог - и любые недостающие директории по пути - и не прерывается, если каталог уже существует, поэтому вы можете сделать все сразу:
mkdir -p /some/directory/you/want/to/exist || exit 1
file="foo"
if [[ -e "$file" ]]; then echo "File Exists"; fi;
Вы считали, что просто делаете то, что хотите сделать в if
, а не смотрите, прежде чем прыгать?
IE, если вы хотите проверить наличие каталога перед его вводом, попробуйте сделать это:
if pushd /path/you/want/to/enter; then
# commands you want to run in this directory
popd
fi
Если путь, который вы даете pushd
, существует, вы введете его, и он выйдет с 0
, что означает then
часть оператор выполнит. Если он не существует, ничего не произойдет (кроме некоторого выхода, говорящего о том, что каталог не существует, что, вероятно, является полезным побочным эффектом в любом случае для отладки).
Кажется лучше, чем это, что требует повторяя себя:
if [ -d /path/you/want/to/enter ]; then
pushd /path/you/want/to/enter
# commands you want to run in this directory
popd
fi
То же самое работает с cd
, mv
, rm
и т. д. ... если вы попробуете их в файлах, которые не существуют, они выйдут с ошибка и напечатать сообщение о том, что его не существует, и ваш блок then
будет пропущен. Если вы попробуете их в существующих файлах, команда выполнит и выйдет со статусом 0
, что позволит выполнить ваш блок then
.
Не забудьте всегда переносить переменные в двойные кавычки, ссылаясь на них в сценарии bash. Дети в эти дни растут с идеей, что они могут иметь пробелы и множество других забавных персонажей в своих именах каталогов.
Однажды один из этих детей запустит ваш скрипт с $DIRECTORY
, установленным на "My M0viez"
, и ваш скрипт взорвется. Вы этого не хотите. Поэтому используйте это.
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
if [ -d /home/ram/dir ] # for file "if [-f /home/rama/file]"
then
echo "dir present"
else
echo "dir not present"
fi
mkdir tempdir # if you want to check file use touch instead of mkdir
ret=$?
if [ "$ret" == "0" ]
then
echo "dir present"
else
echo "dir not present"
fi
Вышеупомянутые скрипты будут проверьте, присутствует ли dir или нет $?
, если последний успешный процесс возвращает значение «0» иначе, отличное от нуля. предположим, что tempdir
уже присутствует, тогда mkdir tempdir
выдаст ошибку, как показано ниже: mkdir: невозможно создать каталог «tempdir»: Файл существует Этот ответ завершен как сценарий оболочки
$ is_dir ~
YES
$ is_dir /tmp
YES
$ is_dir ~/bin
YES
$ mkdir '/tmp/test me'
$ is_dir '/tmp/test me'
YES
$ is_dir /asdf/asdf
NO
# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
echo "Folder doesnt exist: $DIR";
exit;
fi
function show_help()
{
IT=$(CAT <<EOF
usage: DIR
output: YES or NO, depending on whether or not the directory exists.
)
echo "$IT"
exit
}
if [ "$1" == "help" ]
then
show_help
fi
if [ -z "$1" ]
then
show_help
fi
DIR=$1
if [ -d $DIR ]; then
echo "YES";
exit;
fi
echo "NO";
(1)
[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"
(2)
[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"
(3)
[[ -d run_dir && ! -L run_dir ]] && echo Exists || echo "Not Exists"
Если обнаружена проблема с одним из подход, приведенный выше.
С командой ls
; случаи, когда каталог не существует - отображается сообщение об ошибке
$ [[ls -ld SAMPLE_DIR| grep ^d | wc -l
-eq 1]] & amp; & amp; & amp; & amp; & amp; эхо существует || не существует -ksh: not: not found [Нет такого файла или каталога]
Проверьте, существует ли каталог, иначе сделайте один
[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
Если вы хотите проверить, существует ли каталог, независимо от того, является ли это реальным каталогом или символической ссылкой, используйте это:
ls $DIR
if [ $? != 0 ]; then
echo "Directory $DIR already exists!"
exit 1;
fi
echo "Directory $DIR does not exist..."
Объяснение: Команда «ls» дает ошибку «ls: / x: Нет такого файла или каталога ", если каталог или символическая ссылка не существует, а также устанавливает код возврата, который вы можете получить с помощью" $? ", до непустого (обычно" 1 "). Обязательно проверьте код возврата непосредственно после вызова «ls».
Использование проверки -e
будет проверять файлы, и это включает в себя каталоги.
if [ -e ${FILE_PATH_AND_NAME} ]
then
echo "The file or directory exists."
fi
Отличные решения там, но в конечном итоге каждый скрипт будет терпеть неудачу, если вы не находитесь в правильном каталоге. Таким образом, код выглядит следующим образом:
if [ -d "$LINK_OR_DIR" ]; then
if [ -L "$LINK_OR_DIR" ]; then
# It is a symlink!
# Symbolic link specific commands go here
rm "$LINK_OR_DIR"
else
# It's a directory!
# Directory command goes here
rmdir "$LINK_OR_DIR"
fi
fi
будет успешно выполняться только в том случае, если на момент выполнения вы находитесь в директории, в которой есть подкаталог, который вы проверяете.
Насколько я понимаю, начальный вопрос: проверить, существует ли каталог независимо от положения пользователя в файловой системе. Поэтому использование команды «найти» может сделать трюк:
dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d
Это решение хорошо, потому что оно позволяет использовать подстановочные знаки, полезную функцию при поиске файлов / каталогов. Единственная проблема заключается в том, что если искомый каталог не существует, команда «найти» ничего не выведет на stdout (не элегантное решение на мой вкус) и, тем не менее, будет иметь нулевой выход. Может быть, кто-то может улучшить это.
Команда ls
в сочетании с параметром -l
(длинный список) возвращает атрибуты информации о файлах и каталогах. В частности, первый символ выхода ls -l
обычно представляет собой d
или -
(тире). В случае d
список, указанный в списке, является достоверным.
Следующая команда в одной строке сообщит вам, содержит ли данная переменная ISDIR
путь к каталогу или нет:
[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directory"
Практическое использование:
[claudio@nowhere ~]$ ISDIR="$HOME/Music"
[claudio@nowhere ~]$ ls -ld "$ISDIR"
drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
[claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directory"
YES, /home/claudio/Music is a directory.
[claudio@nowhere ~]$ touch "empty file.txt"
[claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt"
[claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
echo "YES, $ISDIR is a directory." ||
echo "Sorry, $ISDIR is not a directoy"
Sorry, /home/claudio/empty file.txt is not a directory
Я нахожу, что версия с двойной скобкой test
делает естественные логические тесты записи:
if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It's a bona-fide directory"
fi
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"
N.B: Котировочные переменные являются хорошей практикой.
blockquote>
Обратите внимание, что тест -d может привести к неожиданным результатам:
$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory
Файл под: «Когда каталог не является каталогом?» Ответ: «Когда это символическая ссылка на каталог». Немного более тщательный тест:
if [ -d t ]; then
if [ -L t ]; then
rm t
else
rmdir t
fi
fi
Более подробную информацию вы можете найти в руководстве Bash в условных выражениях Bash и встроенной команде [
и [[
соединение commmand .
Вы можете использовать test -d
(см. man test
).
blockquote>
-d file
Истина, если файл существует и является каталогом.Для Пример:
test -d "/etc" && echo Exists || echo Does not exist
Примечание: команда
test
такая же, как условное выражение[
(см.man [
), поэтому она переносима по сценариям оболочки.blockquote>
[
- это синоним встроенногоtest
, но последний аргумент должен быть буквальным]
, чтобы соответствовать открытию[
.Для возможные варианты или дополнительную помощь:
help [
help test
man test
илиman [
if [ -d "$DIRECTORY" ]; then
# Here if $DIRECTORY exists
fi
find
found=`find -type d -name "myDirectory"`
if [ -n "$found"]
then
# The variable 'found' contains the full path where "myDirectory" is.
# It may contain several lines if there are several folders named "myDirectory".
fi
found=`find -maxdepth 1 -type d -name "my*"`
if [ -n "$found"]
then
# The variable 'found' contains the full path where folders "my*" have been found.
fi
found=`find -maxdepth 1 -type d -name "myDirectory"`
if [ -n "$found"]
then
# The variable 'found' is not empty => "myDirectory"` exists.
fi
Чтобы проверить несколько каталогов, используйте этот код:
if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
# Things to do
fi
Ниже можно использовать
find . -type d -name dirname -prune -print
Введите этот код в приглашении bash
if [ -d "$DIRECTORY" ]; then
# if true this block of code will execute
fi
Или для чего-то совершенно бесполезного:
[ -d . ] || echo "No"
Чтобы проверить, существует ли каталог, вы можете использовать простую структуру if:
if [ -d directory/path to a directory ] ; then
#Things to do
else #if needed #also: elif [new condition]
# things to do
fi
Вы можете сделать это также в отрицательном
if [ ! -d directory/path to a directory ] ; then
# things to do when not an existing directory
Примечание: будьте осторожны, оставляйте пустые места с обеих сторон обеих открывающих и закрывающих скобок.
С тем же синтаксисом вы можете использовать:
-e: any kind of archive
-f: file
-h: symbolic link
-r: readable file
-w: writable file
-x: executable file
-s: file size greater than zero
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists
fi
Это не совсем верно ... Если вы хотите перейти в этот каталог, вам также необходимо иметь права на выполнение в каталоге. Возможно, вам также понадобятся права на запись.
therfore:
if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
# ... to go to that directory (even if DIRECTORY is a link)
cd $DIRECTORY
pwd
fi
if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
# ... to go to that directory and write something there (even if DIRECTORY is a link)
cd $DIRECTORY
touch foobar
fi
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
Вот очень прагматичная идиома:
(cd $dir) || return # is this a directory,
# and do we have access?
Я обычно обертываю ее в функцию:
can_use_as_dir() {
(cd ${1:?pathname expected}) || return
}
Или:
assert_dir_access() {
(cd ${1:?pathname expected}) || exit
}
Хорошая вещь об этом подходе заключается в том, что мне не нужно думать о хорошем сообщении об ошибке.
cd
даст мне стандартное однострочное сообщение для stderr. Он также предоставит больше информации, чем я могу предоставить. Выполняя cd
внутри подоболочки ( ... )
, команда не влияет на текущий каталог вызывающего. Если каталог существует, эта подоболочка и функция просто отсутствуют.
Далее приведен аргумент, который мы переходим к cd
: ${1:?pathname expected}
. Это более сложная форма замещения параметров, которая более подробно объясняется ниже.
Tl; dr: Если строка, переданная в эту функцию, пуста, мы снова выходим из подоболочки ( ... )
и возвращаемся из функция с данным сообщением об ошибке.
Цитирование с man_страницы ksh93
:
${parameter:?word}
Если
blockquote>parameter
установлено и не имеет значения null, замените его значение; в противном случае напечатайтеword
и выйдите из оболочки (если не интерактивно). Еслиword
опущено, выводится стандартное сообщение.и
Если двоеточие
blockquote>:
опущено из приведенных выше выражений, shell проверяет, установлен ли параметр или нет.Фраза здесь характерна для документации оболочки, так как
word
может ссылаться на любую разумную строку, включая пробелы.В этом конкретном случае я знаю, что стандартного сообщения об ошибке
1: parameter not set
недостаточно, поэтому я увеличиваю тип ожидаемого здесь значения -pathname
каталога.Философская заметка: оболочка не является объектно-ориентированным языком, поэтому сообщение говорит
pathname
, а неdirectory
. На этом уровне я бы предпочел сохранить его простым - аргументы функции являются просто строками.
Более короткая форма:
[ -d "$DIR" ] && echo "Yes"
На самом деле вы должны использовать несколько инструментов для получения пуленепробиваемого подхода:
DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # now you're testing
echo "It's a dir";
fi
Не нужно беспокоиться о пробелах и специальных символах, пока вы используете "${}"
.
Обратите внимание, что [[]]
не так портативен, как []
, но так как большинство людей работают с современными версиями Bash (так как в большинстве случаев большинство людей даже не работают с командной строкой: -p), преимущество больше, чем проблема.