Чи можуть сценарії виконуватись навіть тоді, коли вони не встановлені як виконувані?


25

Я можу, здається, запускати скрипти (.sh) з і без того, щоб вони були встановлені як виконувані. То де саме це має значення?

Відповіді:


24

Скажімо, у вас є файл, myscriptщо містить:

#!/bin/bash
echo "Hello, World!"

Якщо зробити цей файл виконуваним і запустити його ./myscript, тоді ядро ​​побачить, що перші два байти є #!, а це означає, що це файл-скрипт. Потім ядро ​​використовуватиме решту рядка в якості інтерпретатора і передасть файл як перший аргумент. Отже, він працює:

/bin/bash myscript

і bash зчитує файл і виконує команди, які він містить.

Таким чином, для bash (або будь-якого інтерпретатора, який вимагає ваш скрипт) для "виконання" сценарію, він повинен лише вміти читати файл.

Отже, для скриптів біт виконання просто робить його трохи зручнішим. Поки bash виконується, ви завжди можете запускати bash з файлом скрипту як аргумент, або запускати bash інтерактивно та копіювати вставляти сценарій рядок у рядок у свій термінал, щоб виконувати команди.


Дякуємо за детальне пояснення. :) Якщо я зрозумів це правильно, будь-який доступ користувача до bash просто потребує читання доступу до скрипту, щоб його запустити, тому що bash буде приймати скрипт як вхідний і його потрібно буде лише прочитати. Я можу припинити цю поведінку, взявши дозвіл на читання сценарію для цього користувача. Правильно? Отже, коли цей дозвіл на виконання виконується & саме має значення?
Ashfame

Так, якщо ви використовуєте "bash myscript", користувачеві потрібен доступ лише для читання для "myscript" (і, звичайно, виконується для / bin / bash, якщо bash є в межах шляху). Однак якщо ви зробите свій сценарій виконуваним, справи дещо відрізняються. Це правда, що з точки зору ядра, знову буде "/ bin / bash myscript", якщо перший рядок є #! / Bin / bash, але щоб досягти цієї точки, спочатку потрібно представити сценарій як виконуваний для користувач або група. Однак це правда, якщо для певного користувача скрипт є не виконуваним, але читабельним, він все ще може "запустити" скрипт із "bash myscript" ....
ЛГБ

@LGB Так що це майже марно. Добре - вирізати дозвіл на читання від користувача для цього сценарію. Правильно?
Ashfame

@Ashfame: Я б сказав, що корисніший, а не марний. Біт виконання у звичайних файлах не (і ніколи не передбачався) використовується для обмеження доступу. Схоже, ви цього і очікуєте. Якщо у вас є двійковий виконуваний файл, ви повинні мати дозвіл на його виконання для його запуску. Однак якщо ви ознайомилися з доступом до нього, ви завжди можете скопіювати файл у свій домашній каталог, і в такому випадку копія буде належить вам, тож ви можете додати до нього дозвіл на виконання ... та запустити його. Для каталогів він має трохи інше призначення. Дивіться mywiki.wooledge.org/Permissions
geirha

1
Що слід використовувати замість / bin / bash, якщо я не знаю правильного перекладача? Чи є команда, яка виконує сценарій відповідно до рядка shebang?
Айвар

16

Переконайтеся, що ви не плутаєте "виконання сценарію оболонки" з "запуском сценарію оболонки за допомогою sh".

На це не впливатимуть дозволи на файли file.sh:

sh file.sh

Ви виконуєте sh(який вирішує програму /bin/sh), який читає file.shта виконує його код.

Дозволи на файли матимуть силу, якщо ви справді виконуєте сам сценарій :

./file.sh

Зауважте, що дозволи файлів не підтримуються файловими системами, які не є Linux, як FAT. Тож навіть якщо ви запустите chmod -x file.sh, файл все одно матиме попередні дозволи.

Дозвіл на виконання виконується файловою системою. Але програми також можуть "виконати" код, прочитавши вміст файлу, що обходить дозволи файлової системи при "Execute".


Я розумію вашу думку. Але тоді це для групи чи світу чи обох?
Ashfame

@Ashfame Якщо ви встановите дозвіл на виконання, сценарій може запускатися безпосередньо користувачами, які мають цей дозвіл - незалежно від того, чи є вони у групі, світі чи власниках. Але навіть люди без дозволу на виконання можуть виконати це, зателефонувавши на іншу програму (наприклад bash), щоб виконати виконання - щоб заблокувати, що вам доведеться також забрати їх readдозвіл.
jg-faustus

If you set the executable permission, the script can be run directly by users who have that permission - whether they have it on a group, world or owner basisАле як дозвіл надається різним користувачам шляхом перевірки виконавчого дозволу? І я отримав ваше друге бал. Ви маєте на увазі забрати їх дозвіл на читання сценарію, щоб вони навіть не могли обробити його через bash. Правильно?
Ashfame

@Ashfame У пункті дозволу на читання, так. Про те, як би ви викликали щось подібне sudo chmod g+x myfile.shв терміналі, щоб додати дозволи на виконання групи файлів. Див. Посібник з дозволу на файл . Для управління дозволами для декількох користувачів одночасно, ви б використовували групи, див., Наприклад, Управління групами .
jg-faustus

що я мав на увазі, коли ми додавали в GUI дозвіл на виконання, то його для кого? власник / група / світ?
Ashfame

1

Не думайте про це так. Чи можу я виконати цей файл? Подумайте про це так: Хто може виконати цей файл?

Якщо комп'ютер ваш, а файл - ваш, я впевнений, що ви можете його виконати. Ви можете переглянути детальніше такі команди, як chmod та chown , і дозволи на файли.

Я сподіваюся, що це допомагає.


Так, я знаю про них. Це означає, що я (власник) завжди можу це виконати. Правильно? Тоді встановлення файлу як виконуваного виконується для групи, світу чи обох?
Ashfame

1

Система execвиклику ядра Linux не працює, EACCESякщо файл не виконується

У той час як ви можете це робити sh myprog.sh(що тільки читає файли та інтерпретує це), намагаючись запустити програму як ./myprog.shне може працювати, оскільки коли ви це робите:

Це можна підтвердити за допомогою main.c:

#define _XOPEN_SOURCE 700
#include <errno.h>
#include <stdio.h>
#include <unistd.h>

int main(void) {
    char *argv[] = {"myprog", NULL};
    char *envp[] = {NULL};
    int ret;
    ret = execve("myprog.sh", argv, envp);
    perror("execve");
    printf("%d\n", errno);
    printf("%d\n", EACCES);
}

і myprog.sh:

#!/bin/sh
echo worked

Якщо myprog.shце не виконується, mainне вдається:

execve: Permission denied
13
13

Випробувано в Ubuntu 17.10, gcc -std=c99.

POSIX 7 згадує, що:

Функції exec, крім fexecve (), не спрацьовують, якщо:

[EACCES] У дозволі на пошук відмовлено в каталозі, вказаному в префіксі шляху нового файлу образу процесу, або новий файл зображення процесу відхиляє дозвіл на виконання.

Подальше обґрунтування можна знайти на веб-сторінці : /security/66550/unix-execute-permission-can-be-easily-bypassed-is-it-superfluous-or-whats-the

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.