Как я запускаю программу в новой оболочке?

Короче говоря, тот ACK был отправлен, когда сокет не принадлежал никому. Вместо того, чтобы позволить пакеты, которые принадлежат сокету, который принадлежит пользователю x, позвольте пакеты, которые принадлежат соединению, которое инициировалось сокетом от пользователя x.

Более длинная история.

Для понимания проблемы это помогает понять как wget и Запросы HTTP работают в целом.

В

wget http://cachefly.cachefly.net/10mb.test

wget устанавливает соединение TCP к cachefly.cachefly.net, и когда-то установленный отправляет запрос в протоколе HTTP, в котором говорится: "Отправьте мне содержание /10mb.test (GET /10mb.test HTTP/1.1) и между прочим, могли Вы не закрывать соединение после того, как Вы будете сделаны (Connection: Keep-alive). Причина, которую это делает, который является, потому что в случае, если сервер отвечает с перенаправлением для URL на том же IP-адресе, это может снова использовать соединение.

Теперь сервер может ответить с также, "здесь прибывает данные, которые Вы запросили, остерегайтесь, это 10 МБ шириной (Content-Length: 10485760), и да хорошо, я уеду, соединение открывают". Or if it does not know the size of the data, "Вот данные, извините я не могу оставить соединение открытым, но я скажу, когда можно будет прекратить загружать данные путем закрытия моего конца соединения".

В URL выше, мы в первом случае.

Так, как только wget получил заголовки для ответа, он знает, что его задание сделано, после того как он загрузил 10 МБ данных.

В основном, что wget делает считан данные, пока 10 МБ не были получены и выход. Но в той точке, существует больше, чтобы быть сделанным. Что относительно сервера? Этому сказали оставить соединение открытым.

Перед выходом, wget завершения (close системный вызов) дескриптор файла для сокета. На, close, система заканчивает подтверждать данные, отправленные сервером, и отправляет a FIN сказать: "Я не буду отправлять больше данные". В той точке close возвраты и wget выходы. Нет никакого сокета, связанного с соединением TCP больше (по крайней мере, не один принадлежавший никаким пользователем). Однако это еще не закончено. После получения этого FIN, сервер HTTP видит конец файла при чтении следующего запроса от клиента. В HTTP, который не означает "больше запроса, я закрою свой конец". Таким образом, это отправляет свой FIN также, для высказывания, "Я ничего не буду отправлять также, то соединение уходит".

После получения, что FIN, клиент отправляет "ACK". Но, в той точке, wget давно в прошлом, так, чтобы ACK не был ни от какого пользователя. Который является, почему это заблокировано Вашим брандмауэром. Поскольку сервер не получает ACK, он собирается отправить FIN много раз, пока он не сдастся, и Вы будете видеть более отброшенный ACKs. Это также означает путем отбрасывания тех ACKs, бесполезное использование ресурсов сервера (который должен поддержать сокет в состоянии последнего ACK), в течение достаточно долгого времени.

Поведение отличалось бы, если бы клиент не запросил "Активный", или сервер не ответил с "Активным".

Как уже упомянуто, если Вы используете средство отслеживания соединения, что Вы хотите сделать, позволен каждый пакет в УСТАНОВЛЕННЫХ и СВЯЗАННЫХ состояниях через, и только волнуйтесь о NEW пакеты.

Если Вы позволяете NEW пакеты от пользователя x но не пакеты от пользователя y, затем другие пакеты для установленных соединений пользователем x пройдет, и потому что не может быть установленных соединений пользователем y (так как мы блокируемся NEW пакеты, которые установили бы соединение), не будет никакого пакета для пользователя y прохождение через соединений.

2
11.11.2013, 19:09
5 ответов

Разветвление нового процесса сохранит среду.

Если необходимо выполнить процесс с данной средой, все процессы, запущенные этим, будут использовать эту среду, также.

Однако Вы могли сохранить незагрязненную окружающую среду в файл: export >original_env.

Позже Вы могли очистить загрязненное использование среды env -i и импортируйте старую среду путем определения источника того файла.

2
27.01.2020, 22:06
  • 1
    я не должен действительно сохранять ENV, очистку, сбрасывать к ENV по умолчанию, очистке, и затем сбрасывать к сохраненному ENV, который занимает слишком много времени. –  Brian Postow 13.11.2013, 22:19
  • 2
    В этом случае Вам, вероятно, не повезло. Если Ваше переопределение, переменная и не сохраняет исходное значение, у Вас нет способа задержать его к тому значению позже. (И если я понимаю Вас правильно, Вам нужно старое значение позже.) –  michas 13.11.2013, 22:26
  • 3
    Однако это не так сложно, как Вы думаете. Только необходимо сохранить новую окружающую среду однажды. Впоследствии просто необходимо получить его каждый раз, когда Вам нужна новая среда. (Это не должно быть никакой проблемой производительности вообще.) –  michas 13.11.2013, 22:29

Я не уверен, что это оптимально, но я заставил следующее работать в маленьких тестах:

env -i /bin/bash -cl 'COMMAND'

Очевидно, Вы не можете выполнить csh с - статья, потому что-l не может сосуществовать ни с какими другими аргументами..., но в ударе Вы можете.

ETA:

Я думаю, что это - то, что я собираюсь на самом деле использовать:

#!/bin/csh -f
set evs = ""
if ($1 == '--envVars') then
    set envs = "$2"
    shift
    shift
endif

env -i $envs CMD="$*" /bin/bash -c '$CMD'

Это позволяет мне ввести огибающие переменные из командной строки, если я должен, как $PATH и $PYTHONPATH...

1
27.01.2020, 22:06

Самым легким путем я могу думать, к нет export Ваши переменные. В зависимости от Вашего сценария использования это может или не может быть выполнимо. Например:

$ cat a.sh
#!/bin/bash
BAR=foo
export BAZ=foo
bash -c 'echo "bash -c : BAR: $BAR, BAZ: $BAZ"'
echo "normal  : BAR: $BAR, BAZ: $BAZ"

$ ./a.sh
bash -c : BAR: , BAZ: foo
normal  : BAR: foo, BAZ: foo

Поскольку Вы видите в примере выше, оболочка; aunched bash -c будет только иметь доступ к экспортируемым переменным.

0
27.01.2020, 22:06
  • 1
    Нет, я должен экспортировать переменные, потому что высокоуровневая программа является на самом деле несколькими программами, которые называют друг друга. –  Brian Postow 12.11.2013, 16:56
  • 2
    @BrianPostow да, я боялся этого. Работает 'ssh localhost КОМАНДА" опция? –  terdon♦ 12.11.2013, 16:57
  • 3
    Нет, потому что ssh вернется pwd к ~, который может испортить другие вещи. Кроме того, это требует, чтобы или пользователь ввел в пароле или rhosts, который будет настроен, и ни один из тех не работает на эту установку. –  Brian Postow 12.11.2013, 17:03

В зависимости от того, что Вы хотите,

env -i PATH="$(getconf PATH)" HOME="$HOME" USER="$USER" SHELL="$SHELL" "$SHELL" -lc "your command"

попытался бы сбросить стандартную среду для Вашей оболочки. Можно также добавить i к опциям оболочки так, чтобы это было интерактивным.

Кроме того, можно сделать

env > saved.env
...
env -i `cat saved.env` your command

сохранить и восстановить среду. Но необходимо будет обработать saved.env так, чтобы он был правильно заключен в кавычки (у меня есть некоторый огибающий Вар с пробелами и вкладками в их значении).

0
27.01.2020, 22:06

Единственный способ, который я нашел, это использовать sudo, если вам разрешено это делать:

sudo -u "$USER" path_to_script

Пример скрипта:

#!/bin/sh
set | grep ARGH

Использование:

$ export ARGH=yes
$ sudo -u "$USER" ./check_env
(empty line, so ARGH is not set)
0
27.01.2020, 22:06

Теги

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