Как мне установить рабочий каталог родительского процесса?

Я использовал какое-то время для ответа Хамида, но в тех случаях, когда массив языков похож на ["en", "en-GB", "en-US", "fr-FR", "fr" , «en-ZA»], он вернет «en», когда «en-GB» будет лучше соответствовать.

Мое обновление (ниже) вернет первый длинный формат кода, например «en-GB», иначе он вернет первый короткий код, например. «en», иначе он вернет null.

function getFirstBrowserLanguage() {
        var nav = window.navigator,
            browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'],
            i,
            language,
            len,
            shortLanguage = null;

        // support for HTML 5.1 "navigator.languages"
        if (Array.isArray(nav.languages)) {
            for (i = 0; i < nav.languages.length; i++) {
                language = nav.languages[i];
                len = language.length;
                if (!shortLanguage && len) {
                    shortLanguage = language;
                }
                if (language && len>2) {
                    return language;
                }
            }
        }

        // support for other well known properties in browsers
        for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
            language = nav[browserLanguagePropertyKeys[i]];
            len = language.length;
            if (!shortLanguage && len) {
                shortLanguage = language;
            }
            if (language && len > 2) {
                return language;
            }
        }

        return shortLanguage;
    }

console.log(getFirstBrowserLanguage());

23
задан Rob 4 August 2012 в 08:04
поделиться

7 ответов

Не делай этого.

FILE *p;
char cmd[32];
p = fopen("/tmp/gdb_cmds", "w");
fprintf(p, "call chdir(\"..\")\ndetach\nquit\n");
fclose(p);
sprintf(cmd, "gdb -p %d -batch -x /tmp/gdb_cmds", getppid());
system(cmd);

Это будет , вероятно, работать, хотя обратите внимание, что команда Баша pwd кэшируется и не заметит.

32
ответ дан ephemient 4 August 2012 в 08:04
поделиться

Не существует «легального» способа повлиять на текущий каталог родительского процесса, кроме как просто попросить родительский процесс изменить его сам.

chdir, который изменяет каталог в скриптах bash, это не внешняя утилита, а встроенная команда.

6
ответ дан Vlad 4 August 2012 в 08:04
поделиться

Команда chdir является встроенной в оболочку, поэтому она имеет прямой доступ к рабочему каталогу оболочки, которая ее выполняет. Оболочки обычно довольно хорошо защищают себя от воздействия сценариев, предоставляя дочернему процессу копию собственной рабочей среды оболочки. Когда дочерний процесс завершается, среда, которую он использовал, удаляется.

Одна вещь, которую вы можете сделать, это «найти» сценарий. Это позволяет вам изменить каталог, потому что по сути вы указываете оболочке выполнять команды из файла, как если бы вы вводили их напрямую. То есть, вы не работаете с копией среды оболочки, вы работаете непосредственно с ней при поиске.

4
ответ дан JustJeff 4 August 2012 в 08:04
поделиться

Способ , который я решил , состоит в том, чтобы иметь псевдоним оболочки, который вызывает сценарий и создает файл, который написал сценарий. Так, например,

function waypoint {
    python "$WAYPOINT_DIRECTORY"/waypoint.py $@ &&
    source ~/.config/waypoint/scratch.sh
    cat /dev/null > ~/.config/waypoint/scratch.sh
}

и waypoint.py создает scratch.sh, чтобы выглядеть как

cd /some/directory

Это все еще плохая вещь.

3
ответ дан Xiong Chiamiov 4 August 2012 в 08:04
поделиться

Я не уверен, что это « не делай этого » тоже ...

Благодаря чрезвычайно полезному обсуждению в https://unix.stackexchange.com/questions/213799/can-bash-write-to-its-own-input-stream/ ...

Утилита tailcd (для «tail-call cd»), которая работает как в bash, так и под Midnight Commander, позволяет использовать в таких скриптах, как

/ bin / mkcd:

mkdir "$1" && tailcd "$1"

Реализация сложная и требует xdotool. Команда tailcd должна быть последней командой в сценарии (это типичное требование совместимости для утилит, которые допускают несколько реализаций). Он взламывает поток ввода bash, а именно вставляет в него cd <dirname>. В случае Midnight Commander, он дополнительно вставляет две комбинации клавиш Ctrl + O (включение / выключение панелей) и очень хакерским способом использует sleep для межпроцессной синхронизации (что обидно, но работает).

/ bin / tailcd:

#! /bin/bash
escapedname=`sed 's/[^a-zA-Z\d._/-]/\\\\&/g' <<< "$1"`
if [ -z "$MC_TMPDIR" ] ; then
xdotool type " cd $escapedname  "; xdotool key space Return
else
(sleep 0.1; xdotool type " cd $escapedname "; xdotool key space Return Ctrl+o; sleep 0.1; xdotool key Ctrl+o )&
fi

(Пробел перед cd не позволяет вставленной команде перейти в историю; пробелы после имени каталога требуются для его работы, но я этого не делаю знаю почему.)

Другая реализация tailcd не использует xdotool, но она не работает с Midnight Commander:

#!/bin/bash
escapedname=`sed 's/[^a-zA-Z\d._/-]/\\\\&/g' <<< "$1"`
perl -e 'ioctl(STDIN, 0x5412, 

Я не уверен, что это « не делай этого » тоже ...

Благодаря чрезвычайно полезному обсуждению в https://unix.stackexchange.com/questions/213799/can-bash-write-to-its-own-input-stream/ ...

Утилита tailcd (для «tail-call cd»), которая работает как в bash, так и под Midnight Commander, позволяет использовать в таких скриптах, как

/ bin / mkcd:

[110]

Реализация сложная и требует xdotool. Команда tailcd должна быть последней командой в сценарии (это типичное требование совместимости для утилит, которые допускают несколько реализаций). Он взламывает поток ввода bash, а именно вставляет в него cd <dirname>. В случае Midnight Commander, он дополнительно вставляет две комбинации клавиш Ctrl + O (включение / выключение панелей) и очень хакерским способом использует sleep для межпроцессной синхронизации (что обидно, но работает).

/ bin / tailcd:

[111]

(Пробел перед cd не позволяет вставленной команде перейти в историю; пробелы после имени каталога требуются для его работы, но я этого не делаю знаю почему.)

Другая реализация tailcd не использует xdotool, но она не работает с Midnight Commander:

[112]

В идеале, tailcd будет / должно быть часть bash, используйте нормальное межпроцессное взаимодействие и т. д.

) for split "", join " ", @ARGV' " cd" "$escapedname"

В идеале, tailcd будет / должно быть часть bash, используйте нормальное межпроцессное взаимодействие и т. д.

\r'

В идеале, tailcd будет / должно быть часть bash, используйте нормальное межпроцессное взаимодействие и т. д.

0
ответ дан 18446744073709551615 4 August 2012 в 08:04
поделиться

Как именно вы можете изменить рабочий каталог bash (или parent в целом)?

Это не невозможно при использовании любой "приемлемый" способ. Под приемлемым я подразумеваю «без чрезмерного взлома вашей системы (например, используя gdb )»;)

Более серьезно, когда пользователь запускает исполняемый файл, дочерний процесс запускается в его собственная среда, которая в большинстве своем является копией своей родительской среды. Эта среда содержит «переменные среды», а также «текущий рабочий каталог», просто чтобы назвать эти две.

Конечно, процесс может изменить свою собственную среду. Например, чтобы изменить его рабочий каталог (например, когда вы cd xxx в вашей оболочке). Но поскольку эта среда является копией , это никак не меняет среду родителя. И нет никакого стандартного способа изменить вашу родительскую среду.


В качестве примечания, именно поэтому cd ("chdir") является внутренней командой оболочки , а не внешней утилитой . Если бы это было так, он не смог бы изменить рабочий каталог оболочки.
3
ответ дан Sylvain Leroux 4 August 2012 в 08:04
поделиться

Если вы запускаете оболочку в интерактивном режиме, а целевой каталог статичен, вы можете просто поместить псевдоним в свой файл ~/.bashrc:

alias cdfoo='cd theFooDir'

При работе с неинтерактивными сценариями оболочки вы может создать протокол между родительским сценарием Bash и дочерним сценарием Bash. Один из способов реализации этого - позволить дочернему сценарию сохранить путь в файл (например, ~/.new-work-dir). После завершения дочернего процесса родительский процесс должен будет прочитать этот файл (например, cd `cat ~/.new-work-dir`).

Если вы планируете использовать правило, упомянутое в предыдущем абзаце очень часто, я бы посоветовал вам загрузить исходный код Bash и исправить его так, чтобы он автоматически изменял рабочий каталог на содержимое ~/.new-work-dir после каждого запуска команда. В патче вы могли бы даже реализовать совершенно новую встроенную команду Bash, которая соответствует вашим потребностям и реализует протокол, который вы хотите реализовать (эта новая команда, вероятно, не будет принята сопровождающими Bash). Но исправление работает для личного использования и для использования в небольшом сообществе.

0
ответ дан 4 August 2012 в 08:04
поделиться
Другие вопросы по тегам:

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