CommandLine префикс-макро - запустить команду в Bash

Столкнулись с проблемой в использовании Far? Здесь можно получить помощь.
Post Reply
EGez
Posts: 145
Joined: Thu 04 Oct, 2012 13:53
Location: Hamburg, DE
Has thanked: 2 times
Been thanked: 2 times

CommandLine префикс-макро - запустить команду в Bash

Post by EGez »

Доброй ночи.

Вопрос к гуру у меня.

По работе и дома приходится очень часто пользоваться другими командными интерпретерами вроде Bash.

Для того, чтобы запускать некоторые команды напрямую из Far, пытаюсь для этого использовать CommandLine макро:

Code: Select all

CommandLine {
	prefixes = 'bash'; action = function(prefix, cmd)
		panel.GetUserScreen()
		pcall(function()
			os.execute(("bash -xc %q"):format(cmd))
		end)
		panel.SetUserScreen()
	end;
}
Вроде бы работает, но только если команда полностью состоит из (в моем случае) АСКИИ знаков.

Code: Select all

bash:find directory 
+ find directory
directory
directory/file
directory/файл
Если же команда вдруг содержит национальные знаки вроде кириллицы или немецких умляутов, то получается вот такой вот бред:

Code: Select all

bash:find папка 
+ 'find папка'
bash: find папка: command not found
Обратите внимание и на кавычки в команде. Пробовал выдавать результат вызова :format() перед выполнением, разницы не вижу никакой, все показывается нормально.

Что-то квотит команду полностью и кодировка не совпала похоже.

Несколько месяцев уже думаю над этим, ничего в голову не приходит...

Что я делаю не так? Как научить его?

Windows 7, Far 3.0.5279, Bash 4.4.19 из MSYS2.

Спасибо
Yegor
Posts: 1326
Joined: Mon 04 Apr, 2005 13:41
Location: San Ramon, CA / Kharkov, UA
Has thanked: 32 times
Been thanked: 61 times

CommandLine префикс-макро - запустить команду в Bash

Post by Yegor »

search.php?keywords=os.execute+utf

Первая ссылка.

EDIT: даже без ссылок, в результатах поиска есть ответ.
Last edited by Yegor on Sat 27 Oct, 2018 00:05, edited 1 time in total.
Мы не можем ждать милостей от Фара, взять их у него — наша задача! (C) Мичурин
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

CommandLine префикс-макро - запустить команду в Bash

Post by buniak_a_h »

1.
2. Простой способ - перекодировать командную строку, передаваемую интерпретатору, в ANSI:

Code: Select all

local function UTF_8ToANSI(str)
  return win.WideCharToMultiByte(win.MultiByteToWideChar(str, 65001), win.GetACP())
end
os.execute(win.Utf8ToOem('cmd /C echo проба'))
Проверено на cmd, но не думаю, что будет разница с Bash
Last edited by buniak_a_h on Sat 27 Oct, 2018 02:32, edited 1 time in total.
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

CommandLine префикс-макро - запустить команду в Bash

Post by Shmuel »

EGez, попробуйте в вашей функции action заменить os.execute на win.system. Возможно, что этого будет достаточно.
EGez
Posts: 145
Joined: Thu 04 Oct, 2012 13:53
Location: Hamburg, DE
Has thanked: 2 times
Been thanked: 2 times

CommandLine префикс-макро - запустить команду в Bash

Post by EGez »

Yegor wrote: Fri 26 Oct, 2018 23:55 Первая ссылка.
Да, Егор, спасибо за ответ, но:
У меня ANSI - это 1252, а OEM - 850, в них нет аналогов кириллице.
И соответственно:
И если в пути присутствует что-то, не имеющее соответствия в ANSI, то будет ошибка.
EGez
Posts: 145
Joined: Thu 04 Oct, 2012 13:53
Location: Hamburg, DE
Has thanked: 2 times
Been thanked: 2 times

CommandLine префикс-макро - запустить команду в Bash

Post by EGez »

Shmuel wrote: Sat 27 Oct, 2018 08:15 EGez, попробуйте в вашей функции action заменить os.execute на win.system. Возможно, что этого будет достаточно.
Тут уже движение какое-то:

Code: Select all

bash:find папка
+ 'find папка'
bash: find папка: command not found
Кодировка похоже прошла нормально. И квотится вроде как bash -xc "find папка", но потом обрамляет всю команду в кавычки и, похоже, пытается это как единую команду выполнить, включая аргумент.

Для сравнения (без кавычек):

Code: Select all

bash:find directory
+ find directory
directory
directory/file
directory/файл
Не понимаю.
EGez
Posts: 145
Joined: Thu 04 Oct, 2012 13:53
Location: Hamburg, DE
Has thanked: 2 times
Been thanked: 2 times

CommandLine префикс-макро - запустить команду в Bash

Post by EGez »

Ага, попробовал напрямую:

Code: Select all

... >bash -xc "find папка"
+ 'find папка'
/usr/bin/bash: find папка: command not found

... >bash -xc "find directory"
+ find directory
directory
directory/file
directory/файл
Походу Баш ее сам квотит.
User avatar
DrKnS
Posts: 6114
Joined: Thu 04 Aug, 2005 06:44
Location: Kyiv
Has thanked: 12 times
Been thanked: 426 times

CommandLine префикс-макро - запустить команду в Bash

Post by DrKnS »

Code: Select all

D:\dev\far_git\FarManager\far>bash --version
GNU bash, version 4.3.42(5)-release (x86_64-pc-msys)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

D:\dev\far_git\FarManager\far>bash -xc "find папка"
+ find папка
find: '\320\277\320\260\320\277\320\272\320\260': No such file or directory
Yegor
Posts: 1326
Joined: Mon 04 Apr, 2005 13:41
Location: San Ramon, CA / Kharkov, UA
Has thanked: 32 times
Been thanked: 61 times

CommandLine префикс-макро - запустить команду в Bash

Post by Yegor »

Я давно себе сделал тупой макрос и забыл:

Code: Select all

Macro {
  area = "Shell";
  key = "CtrlShiftEnter";
  description = "Execute bash command";
  
  action = function()
	local cmdLine = panel.GetCmdLine()
	Keys("Esc")
	print("bash -c \"" .. cmdLine .. "\"")
	Keys("Enter")
  end;
}

Code: Select all

C:\Far\Profile\Macros\scripts>bash --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

C:\Far\Profile\Macros\scripts>bash -c "find папка"
папка
Last edited by Yegor on Tue 30 Oct, 2018 23:31, edited 1 time in total.
Мы не можем ждать милостей от Фара, взять их у него — наша задача! (C) Мичурин
EGez
Posts: 145
Joined: Thu 04 Oct, 2012 13:53
Location: Hamburg, DE
Has thanked: 2 times
Been thanked: 2 times

CommandLine префикс-макро - запустить команду в Bash

Post by EGez »

Yegor wrote: Tue 30 Oct, 2018 23:29 Я давно себе сделал тупой макрос и забыл
[...]
Егор, я давно пытаюсь намекнуть, что у меня "винда" не русская. У меня нет кириллических знаков в стандартных кодировках. А поменять я ее по некоторым причинам не могу.

И да:

Code: Select all

... >bash --version
GNU bash, version 4.4.19(3)-release (i686-pc-msys)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Похоже это не совсем тривиально...
EGez
Posts: 145
Joined: Thu 04 Oct, 2012 13:53
Location: Hamburg, DE
Has thanked: 2 times
Been thanked: 2 times

CommandLine префикс-макро - запустить команду в Bash

Post by EGez »

Добрый вечер.

Кажется я нашел:
Проблема была в том, что однажды я установил переменную LC_ALL=C.UTF-8, что переписывало все и привело к тому, что Баш не совсем правильно рассматривал non-ASCII символы.

Дабы не спровоцировать больших изменений, попробовал просто указать LC_CTYPE=en_US.UTF-8, а остальное оставил C.UTF-8.

И получилось:

Code: Select all

CommandLine {
	prefixes = 'bash'; description = 'Execute with bash'; action = function(prefix, cmd)
		panel.GetUserScreen()
		pcall(function()
			win.system(('bash -xc %q'):format(cmd))
		end)
		panel.SetUserScreen()
	end;
}

Code: Select all

bash:find "с пробелом"
+ find 'с пробелом'
с пробелом
с пробелом/file
с пробелом/файл
Суть проблемы описана так:
The C locale is a special locale that is meant to be the simplest locale. You could also say that while the other locales are for humans, the C locale is for computers. In the C locale, characters are single bytes, the charset is ASCII (well, is not required to, but in practice will be in the systems most of us will ever get to use), the sorting order is based on the byte values, the language is usually US English (though for application messages (as opposed to things like month or day names or messages by system libraries), it's at the discretion of the application author) and things like currency symbols are not defined.
Всем спасибо.
Last edited by EGez on Mon 05 Nov, 2018 22:53, edited 2 times in total.
Post Reply

Return to “Нужна помощь”