Команда, чтобы проверить, имеет ли текущий пользователь права на запись

Мне нужно создать скрипт, чтобы проверить, имеет ли текущий пользователь права на запись в файл. Если нет, должна появиться ошибка.

Я написал это:

if [namei -m /path/to/textfile.txt | grep w]; then echo "message"

Но я, кажется, получаю синтаксическую ошибку.

3
задан 27 November 2017 в 17:42

2 ответа

Давайте рассмотрим проблемы с вашим кодом. В качестве десерта, упомянутого в комментарии, первой проблемой является синтаксис команды [. Нам нужно поместить пробелы между [ и его аргументами, потому что оболочка использует пробелы для разделения полей и думает, что [namei - это команда, которую вы хотите запустить.

Я собираюсь использовать файл в моем домашнем каталоге под названием file, который, как я знаю, у меня есть разрешение на запись в моих примерах. Я поставил ваш код на одну строку, чтобы было проще протестировать интерактивно. Он будет работать так же, как если бы после then появилась новая строка.

$ if [namei -m playground | grep w]; then echo "writeable" No command '[namei' found, did you mean: Command 'namei' from package 'util-linux' (main) [namei: command not found

Исправьте пробелы вокруг [ и ]:

$ if [ namei -m playground | grep w ]; then echo "writeable" >

Теперь я получаю приглашение ввести что-то, >. В подсказке сообщается, что оболочка ждет меня, чтобы что-то ввести. Простейшей формой синтаксиса if является

if condition; then command; fi

, поэтому оболочка ждет fi. Если я введу его в подсказку, я получу это:

$ if [ namei -m file | grep w ]; then echo "writeable" > fi bash: [: missing `]' grep: ]: No such file or directory

Похоже, что здесь проблема | вызывает проблемы, так как [ не может найти свой последний аргумент, а grep считает, что его последним аргументом является ]. Поскольку [ (или тот, который мы здесь используем), является встроенной оболочкой, мы можем получить некоторую информацию об этом, используя help

$ help [ [: [ arg... ] Evaluate conditional expression. This is a synonym for the "test" builtin, but the last argument must be a literal `]', to match the opening `['.

Мы не можем использовать в середине аргументов команды. В других ситуациях мы могли бы поместить команды в подоболочку, включив их в ( ), но это синтаксическая ошибка в [ (и test).

Настоящая проблема заключается в том, что то, что мы пытаемся передать команде [, не может быть оценено как true или false. Если аргумент, который вы пытаетесь передать в test, является командой, test не использует статус выхода этой команды, как я думаю, вы ожидаете. Вы можете передать вывод команды в [, используя комментарий , но это не то, что вы или ваш код хотите делать.

Я думаю, что ваш код пытается проверить, что grep нашел w в выводе namei -m somefile. Для этого нам не нужна команда test.

$ help if if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi Execute commands based on conditional. The `if COMMANDS' list is executed. If its exit status is zero, then the `then COMMANDS' list is executed. Otherwise, each `elif COMMANDS' list is executed in turn, and if its exit status is zero, the corresponding `then COMMANDS' list is executed and the if command completes. Otherwise, the `else COMMANDS' list is executed, if present. The exit status of the entire construct is the exit status of the last command executed, or zero if no condition tested true.

Итак, если нас интересует только успешная команда, мы можем поместить эту команду в качестве условия для if:

$ if namei -m file | grep w; then echo "writeable"; fi -rw-rw-r-- file writeable

Вы можете даже использовать -q для подавления вывода из grep и собирать только его статус выхода (успех, если совпадение найдено):

$ if namei -m file | grep -q w; then echo "writeable"; fi writeable

Но это не лучший способ проверить, является ли файл доступным для вас. Попробуем еще один тестовый файл:

$ touch file_with_w $ chmod 444 file_with_w $ stat -c %A file_with_w -r--r--r-- $ if namei -m file_with_w | grep -q w; then echo "writeable"; fi writeable

Если мы проанализируем вывод namei -m для файла с именем w в его имени, этот метод заставит его отображаться, даже если он читайте только для всех.

Разбор вывода команд иногда является правильным способом получения требуемой информации. Но обычно есть лучший способ, в виде опции для этой команды, или другая команда с аналогичной целью.

Вернемся к команде test aka [ и посмотрим, имеет любые полезные варианты. Вы можете ввести help test или более подробно прочитать раздел «Условные выражения» в руководстве Bash

File operators: ... -w FILE True if the file is writable by you.

Aha! команда test имеет именно то, что мы хотим, как упоминалось в ответ на раздел Условные выражения

$ if [ -w file ]; then echo "writeable"; fi writeable $ if [ -w file_with_w ]; then echo "writeable"; fi $

Правильно:)

Но вы что вы хотите, чтобы команда выводила сообщение об ошибке, если файл не записывается, а не заявление о его возможности записи. Для этого нам нужен оператор else

$ if [ -w file_with_w ]; then echo "writeable"; else echo "not writeable"; fi not writeable

Как скрипт, вы можете написать эту команду следующим образом:

#!/bin/bash if [ -w "$1" ]; then echo "writeable" else echo "not writeable" fi

Тогда вы могли бы дать ему разрешение на выполнение (заменить script с фактическим именем файла)

chmod u+x script

и запустите его с файлом, который вы хотите проверить в качестве его аргумента (ссылка на скрипт с $1):

$ ./script file writeable $ ./script file_with_w not writeable

Если вы вывод хотите получить сообщение об ошибке, когда файл не записывается и не выводится, когда он есть, вы можете отменить условие теста вместо записи else:

$ if [ ! -w file_with_w ]; then echo "not writeable"; fi not writeable

Как упоминала Пантер в комментарии, вы также можете использовать переменную $USER, которая должна быть расширена до имени пользователя, запускающего оболочку. Вы можете сделать более впечатляющее сообщение об ошибке:

$ if [ ! -w file_with_w ]; then echo "file is not writeable by $USER"; fi file is not writeable by zanna

Для простых команд test вы также можете использовать [ и test и [[ без if и использовать оболочку операторы для логики:

$ [ -w file_with_w ] || echo "not writeable" not writeable

|| является логическим ИЛИ. Это означает, что если предыдущая команда завершилась неудачно, выполните следующую команду

Логический логический код И &&:

$ [ ! -w file_with_w ] && echo "not writeable" not writeable

&& означает , если предыдущая команда не удалось, затем выполните следующую команду

Все это работает, потому что команда test дает полезный статус выхода, как описано в help test:

Exit Status: Returns success if EXPR evaluates to true; fails if EXPR evaluates to false or an invalid argument is given.
5
ответ дан 18 July 2018 в 02:30

Давайте рассмотрим проблемы с вашим кодом. В качестве десерта, упомянутого в комментарии, первой проблемой является синтаксис команды [. Нам нужно поместить пробелы между [ и его аргументами, потому что оболочка использует пробелы для разделения полей и думает, что [namei - это команда, которую вы хотите запустить.

Я собираюсь использовать файл в моем домашнем каталоге под названием file, который, как я знаю, у меня есть разрешение на запись в моих примерах. Я поставил ваш код на одну строку, чтобы было проще протестировать интерактивно. Он будет работать так же, как если бы после then появилась новая строка.

$ if [namei -m playground | grep w]; then echo "writeable" No command '[namei' found, did you mean: Command 'namei' from package 'util-linux' (main) [namei: command not found

Исправьте пробелы вокруг [ и ]:

$ if [ namei -m playground | grep w ]; then echo "writeable" >

Теперь я получаю приглашение ввести что-то, >. В подсказке сообщается, что оболочка ждет меня, чтобы что-то ввести. Простейшей формой синтаксиса if является

if condition; then command; fi

, поэтому оболочка ждет fi. Если я введу его в подсказку, я получу это:

$ if [ namei -m file | grep w ]; then echo "writeable" > fi bash: [: missing `]' grep: ]: No such file or directory

Похоже, что здесь проблема | вызывает проблемы, так как [ не может найти свой последний аргумент, а grep считает, что его последним аргументом является ]. Поскольку [ (или тот, который мы здесь используем), является встроенной оболочкой, мы можем получить некоторую информацию об этом, используя help

$ help [ [: [ arg... ] Evaluate conditional expression. This is a synonym for the "test" builtin, but the last argument must be a literal `]', to match the opening `['.

Мы не можем использовать в середине аргументов команды. В других ситуациях мы могли бы поместить команды в подоболочку, включив их в ( ), но это синтаксическая ошибка в [ (и test).

Настоящая проблема заключается в том, что то, что мы пытаемся передать команде [, не может быть оценено как true или false. Если аргумент, который вы пытаетесь передать в test, является командой, test не использует статус выхода этой команды, как я думаю, вы ожидаете. Вы можете передать вывод команды в [, используя комментарий , но это не то, что вы или ваш код хотите делать.

Я думаю, что ваш код пытается проверить, что grep нашел w в выводе namei -m somefile. Для этого нам не нужна команда test.

$ help if if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi Execute commands based on conditional. The `if COMMANDS' list is executed. If its exit status is zero, then the `then COMMANDS' list is executed. Otherwise, each `elif COMMANDS' list is executed in turn, and if its exit status is zero, the corresponding `then COMMANDS' list is executed and the if command completes. Otherwise, the `else COMMANDS' list is executed, if present. The exit status of the entire construct is the exit status of the last command executed, or zero if no condition tested true.

Итак, если нас интересует только успешная команда, мы можем поместить эту команду в качестве условия для if:

$ if namei -m file | grep w; then echo "writeable"; fi -rw-rw-r-- file writeable

Вы можете даже использовать -q для подавления вывода из grep и собирать только его статус выхода (успех, если совпадение найдено):

$ if namei -m file | grep -q w; then echo "writeable"; fi writeable

Но это не лучший способ проверить, является ли файл доступным для вас. Попробуем еще один тестовый файл:

$ touch file_with_w $ chmod 444 file_with_w $ stat -c %A file_with_w -r--r--r-- $ if namei -m file_with_w | grep -q w; then echo "writeable"; fi writeable

Если мы проанализируем вывод namei -m для файла с именем w в его имени, этот метод заставит его отображаться, даже если он читайте только для всех.

Разбор вывода команд иногда является правильным способом получения требуемой информации. Но обычно есть лучший способ, в виде опции для этой команды, или другая команда с аналогичной целью.

Вернемся к команде test aka [ и посмотрим, имеет любые полезные варианты. Вы можете ввести help test или более подробно прочитать раздел «Условные выражения» в руководстве Bash

File operators: ... -w FILE True if the file is writable by you.

Aha! команда test имеет именно то, что мы хотим, как упоминалось в ответ на раздел Условные выражения

$ if [ -w file ]; then echo "writeable"; fi writeable $ if [ -w file_with_w ]; then echo "writeable"; fi $

Правильно:)

Но вы что вы хотите, чтобы команда выводила сообщение об ошибке, если файл не записывается, а не заявление о его возможности записи. Для этого нам нужен оператор else

$ if [ -w file_with_w ]; then echo "writeable"; else echo "not writeable"; fi not writeable

Как скрипт, вы можете написать эту команду следующим образом:

#!/bin/bash if [ -w "$1" ]; then echo "writeable" else echo "not writeable" fi

Тогда вы могли бы дать ему разрешение на выполнение (заменить script с фактическим именем файла)

chmod u+x script

и запустите его с файлом, который вы хотите проверить в качестве его аргумента (ссылка на скрипт с $1):

$ ./script file writeable $ ./script file_with_w not writeable

Если вы вывод хотите получить сообщение об ошибке, когда файл не записывается и не выводится, когда он есть, вы можете отменить условие теста вместо записи else:

$ if [ ! -w file_with_w ]; then echo "not writeable"; fi not writeable

Как упоминала Пантер в комментарии, вы также можете использовать переменную $USER, которая должна быть расширена до имени пользователя, запускающего оболочку. Вы можете сделать более впечатляющее сообщение об ошибке:

$ if [ ! -w file_with_w ]; then echo "file is not writeable by $USER"; fi file is not writeable by zanna

Для простых команд test вы также можете использовать [ и test и [[ без if и использовать оболочку операторы для логики:

$ [ -w file_with_w ] || echo "not writeable" not writeable

|| является логическим ИЛИ. Это означает, что если предыдущая команда завершилась неудачно, выполните следующую команду

Логический логический код И &&:

$ [ ! -w file_with_w ] && echo "not writeable" not writeable

&& означает , если предыдущая команда не удалось, затем выполните следующую команду

Все это работает, потому что команда test дает полезный статус выхода, как описано в help test:

Exit Status: Returns success if EXPR evaluates to true; fails if EXPR evaluates to false or an invalid argument is given.
5
ответ дан 24 July 2018 в 17:34

Другие вопросы по тегам:

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