Подружить Far и bash (Cygwin и другие)

Хотите говорить о Far и не знаете, куда обратиться?
2useven10
Posts: 4111
Joined: Mon 07 Sep, 2009 10:40
Has thanked: 5 times
Been thanked: 194 times

Подружить Far и bash (Cygwin и другие)

Post by 2useven10 »

Latest post of the previous page:

DrKnS wrote: Команда, начинающаяся с %comspec% /c, будет так выполняться
Только, если /c отрабатывается как в cmd.exe
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

DrKnS wrote:
gene.pavlovsky wrote: Я сомневаюсь, что это возможно...
https://google.com/search?q=regex+match+not+in+quotes
Понял, я просто look-behind в regexp ранее не пользовался. Попробую завтра изобразить регэксп тогда.
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

DrKnS wrote:Ну в процитированном же всё написано: изобразите регекс, который матчит дефолтный "<>|& не в кавычках" - добавим.
В фаре увидел RegExp.cpp/hpp, только не знаю, как им пользоваться. Просто подключение RegExp.hpp к пустому проекту Win32 Console application в VS 2015 выдаёт кучу ошибок при попытке компиляции.

В-общем, я пробовал с std::regex, но вот только они не поддерживают lookbehind.
Если с lookbehind (например PCRE), то:
(?<=^(?:[^"]*|"[^"]*")*)[<>|&]
Тестил в RegexBuddy (тип регэкспа - PCRE или C#).

Без lookbehind-а, работает с std::regex:
^(?:[^\"]|\"[^\"]*\")*?[<>|&]

Code: Select all

#include <iostream>
#include <regex>

using namespace std;

void testRX(wstring str, wregex rx, bool expectedResult) {
	bool result = regex_search(str, rx);
	wcout << L"\"" << str << L"\": " << endl << "  " << (result ? "true" : "false");
	if (result != expectedResult)
		wcout << L" FAILED";
	wcout << endl;
}

int main() {
	wregex tooComplexRX(L"^(?:[^\"]|\"[^\"]*\")*?[<>|&]");
	testRX(L"grep word file", tooComplexRX, false);
	testRX(L"grep \"[<>|&]\" file", tooComplexRX, false);
	testRX(L"echo \"&\"", tooComplexRX, false);
	testRX(L"grep word file | grep word2", tooComplexRX, true);
	testRX(L"grep word file && echo found", tooComplexRX, true);
	testRX(L"backup 2>err.log", tooComplexRX, true);
}
Last edited by gene.pavlovsky on Thu 01 Jan, 1970 01:00, edited 0 times in total.
Reason: [c]
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

DrKnS Спасибо за добавленную опцию far:config System.Executor.ComspecCondition!
http://bugs.farmanager.com/view.php?id=3223#c14595
Если ничего не указывать, то используется проверка на "<>|& не в кавычках" (список символов заключён в [] в конце)
А вот, к примеру, как сделать "[(<>|& не в кавычках": ^(?:[^\"]|\"[^\"]*\")*?[[(<>|&]
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

А вот что я установил в качестве System.Executor.ExcludeCmds для bash:
(;((;.;:;[;[[;bind;builtin;case;command;coproc;declare;echo;eval;exec;exit;export;false;for;function;help;if;kill;let;mapfile;printf;read;readarray;readonly;select;shopt;source;test;time;trap;true;type;ulimit;umask;until;while;{;make
С этими ExcludeCmds, кстати, в большинстве случаев ComspecCondition и не нужен. А ежели не охота использовать ComspecCondition, то можно перед любой командой написать :;, : в bash - команда no-op (ничего не делать).
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

Вкратце - вот что я использую на данный момент.
set ComSpec=C:\cygwin\usr\local\bin\bashcmd.exe
Это устанавливается в макросе Bash.lua, который выполняется при старте фара. Также макрос предоставляет горячие клавиши для переключения ComSpec-а bash<->cmd, выполнения текущей команды через альтернативный (не текущий) ComSpec, и запуска интерактивного bash-а.

bashcmd.exe - написанный мною на С++ wrapper (я использовал VS2015), принимает командную строку, если команда имеет расширение bat|cmd|vbs|vbe|js|jse|wsf|wsh|msc, то запускает её через cmd, иначе оформляет как надо кавычки, и запускает её через bash-wrapper скрипт, путь к нему определяется переменной среды BASHCMD, а если она не определена, по умолчанию используется C:/cygwin/usr/local/bin/bashcmd.sh или (если перекомпилить bashcmd.exe под 64-бит архитектуру) C:/cygwin64/usr/local/bin/bashcmd.sh. Примечание: дочерний процесс запускается с переменной среды ComSpec, установленной в стандартный путь к cmd.exe. Таким образом, если запускается, к примеру, bat-файл, то у него не возникнет проблем с выполнением каких-либо ещё bat-файлов или команд через ComSpec.

bashcmd.sh - малюсенький bash-скрипт, который подключает доп функции, переменные среды, алиасы, опции шелла и т.д. путём включения созданного мною /etc/bash.bashcmdrc, а затем собственно выполняет команду.

Если установить переменную среды BASHCMD_DEBUG=1 (или любое другое не-пустое значение), то оба wrapper-а bashcmd.exe и bashcmd.sh будут при запуске выводить некоторое количество отладочной информации. Это, в частности, позволяет легко различить, выполняется ли конкретная команда через ComSpec, или же Фар выполняет её напрямую (direct run).

/etc/bash.bashcmdrc - мой файл, подгружает алиасы, доп. функции, устанавливает некоторые переменные окружения и опции shell-а (shopt). Так как shell запускается как не-интерактивный, то перед загрузкой алиасов необходимо установить shopt -s expand_aliases.

Настройки far:config
System.Executor.ExcludeCmds: (;((;.;:;[;[[;bind;builtin;case;command;coproc;declare;echo;eval;exec;exit;export;false;for;function;help;if;kill;let;mapfile;printf;read;readarray;readonly;select;shopt;source;test;time;trap;true;type;ulimit;umask;until;while;{;make
System.Executor.ComspecCondition: ^(?:[^\"]|\"[^\"]*\")*?[[({$;<>|&]
System.Executor.ComspecArguments: /S /C "{0}" (значение по умолчанию)

Вот архив со всем вышеупомянутым:
far_bash_comspec.7z
(59.82 KiB) Downloaded 133 times
Или (этот будет обновляться по мере каких-либо изменений):
https://dl.dropboxusercontent.com/u/494 ... comspec.7z

Разработчикам (DrKnS в особенности) огромное спасибо за внесённые изменения, в результате которых всё это стало возможным!
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

Теперь такой вопрос, а всё-таки можно ли как-нибудь из макроса менять значения far:config-а?
У меня в макросе есть переключение ComSpec bash<->cmd по горячей клавише. При этом меняется собственно переменная ComSpec. Но надо бы ещё по-хорошему поставить соответствующие System.Executor.ExcludeCmds, System.Executor.ComspecCondition.
User avatar
Smitis
Posts: 1639
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 20 times
Been thanked: 41 times

Подружить Far и bash (Cygwin и другие)

Post by Smitis »

System.Executor.ExcludeCmds можно менять через переменные среды.
Разум когда-нибудь победит.
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

Smitis wrote:System.Executor.ExcludeCmds можно менять через переменные среды.
Как именно? Что насчёт ComspecCondition?
User avatar
Smitis
Posts: 1639
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 20 times
Been thanked: 41 times

Подружить Far и bash (Cygwin и другие)

Post by Smitis »

gene.pavlovsky wrote:Как именно?
В параметре можно использовать переменные среды в виде %FAR_ExcludeCmds% (это переменная, которую я использую).
Для ComspecCondition такого, кажется, нет (надо уточнить), но можно попросить сделать (заодно и для ComspecArguments).
Разум когда-нибудь победит.
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

Попробую. Есть ещё такая проблемка, не знаю, какое даже решение предложить.
Если я запускаю .bat файл, он внутри call другие .bat файлы с настройками и ещё всякое делает. Если стоит ComSpec bash, сам .bat файл запускается успешно через cmd (direct run, ComSpec не используется), но то, что внутри .bat файла делается - использует ComSpec, в итоге выдаются некоторые ошибки. Если в начале .bat файла прописать set ComSpec=...\cmd.exe, то всё отрабатывает как надо. В моём bashcmd wrapper-е я сделал, чтоб .bat и другие виндовые скрипты запускались через cmd, а не bash, и при этом перед запуском процесса wrapper устанавливает ComSpec=...\cmd.exe. Т.е. если я запускаю, например, мой run.bat | cat (через comspec), то всё отрабатывает как надо, если просто run.bat (direct run), имеются проблемы из-за переменной ComSpec.
Может быть, добавить в фар поддержку новой переменной FAR_ComSpec, которая будет переопределять ComSpec только для команд, исполняемых фаром с командной строки? Тогда можно было бы оставить ComSpec стандартный виндовый, а FAR_ComSpec поставил в bashcmd.exe. Тогда и ком строка будет работать через bash, и .bat и прочие скрипты не будут ломаться.
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

Понял, это разумно. Лучше это обсуждение вынести в отдельную тему, по-моему. С cygwin-ом это лишь весьма отдалённо связано.
Я же предлагаю добавить в Фар поддержку переменной среды FAR_ComSpec, которая (если определена), будет использоваться вместо ComSpec. Тогда можно оставлять стандартный ComSpec нетронутым, все .bat и прочие скрипты, вызывающие внутри другие скрипты, будут и дальше работать без ошибок, а FAR_ComSpec по сути будет выполнять лишь ком строку фара, и ни на что более не будет влиять.
Last edited by gene.pavlovsky on Thu 01 Jan, 1970 01:00, edited 0 times in total.
Reason: Добавлены ссылки на отделённую тему
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

Обновил wrapper, добавил описание получше. Всё внутри архива
https://www.dropbox.com/s/9h50rdq1pmdh4 ... ec.7z?dl=0

Требует Far 3.0 build 4722 или более новый.
Теперь для опций far:config используются переменные среды, так что макрос, переключащий bash/cmd, настраивается теперь более гибко.
Вместо ComSpec теперь используется переменная FAR_ComSpec (на которую указывает System.Executor.Comspec).

Добавлена поддержка многострочных команд (содержащих \n или \r).
Last edited by gene.pavlovsky on Fri 15 Sep, 2017 12:10, edited 1 time in total.
gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

Обновление макроса для ввода многострочных комманд. Теперь по нажатию RCtrlE в Command History текущая команда будет открыта в редакторе, а после сохранения появится на командной строке.

gene.pavlovsky
Posts: 166
Joined: Tue 16 Feb, 2010 17:55
Has thanked: 11 times
Been thanked: 8 times

Подружить Far и bash (Cygwin и другие)

Post by gene.pavlovsky »

bashcmd обновлён, новая ссылка https://www.dropbox.com/s/21uhslqemjx7j ... md.7z?dl=0
Changes:
Fix an issue with \-handling in comspec condition and command line regexp
Add printfcmd.c (for debugging)
Bash.lua: Improve bash comspec condition. Allow different bash command line when running under ConEmu.
bashcmd.cpp: Pause on errors if BASHCMD_DEBUG is set to pause
User avatar
John Doe
Бюрократ
Posts: 12896
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 38 times
Been thanked: 296 times

Подружить Far и bash (Cygwin и другие)

Post by John Doe »

А не лучше ли приаттачить файл тут, на форуме, в шапке темы?
Post Reply

Return to “Обсуждение Far Manager”