В рамках проекта с открытым исходным кодом я пишу сценарий, который позволит разместить агента Jenkins в качестве службы.
Дженкинс работает на Java, поэтому мне пришлось вызвать Java.exe.
Для этого мне нужно убедиться, что при завершении сценария завершается и Java-процесс.
Я обнаружил, что использование CMD /c или Start-Process запускает новый процесс, и поэтому остановка сценария PowerShell не останавливает также java.exe.
Единственное, что работало, это звонок оператора &.
Однако, как вы видите ниже, информация, возвращаемая из JAVA, рассматривается как исключение. ЭТО ЛОЖНО-ПОЛОЖИТЕЛЬНО.
Мне нужно убедиться, что фактическая информация отправляется на вывод как обычно, а не скрыта.
Это исключает $ErrorActionPreference = 'SilentlyContinue'
Также пробовал 2>&1 и *>&1, но результат тот же
Любые идеи будут великолепны.
& "$Java\java.exe" -jar "$JenkinsPath\agent.jar" -url "$JenkinsURL/" -secret $Secret -name $env:computername -workDir "$JenkinsPath" *>>"$JenkinsPath\agent.log"
java.exe : Aug 04, 2024 5:14:14 PM org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir
At line:1 char:1
+ & "$Java\java.exe" -jar "$JenkinsPath\agent.jar" -url "$JenkinsURL/" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Aug 04, 2024 5:...itializeWorkDir:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
INFO: Using D:\Jenkins\remoting as a remoting work directory
Aug 04, 2024 5:14:14 PM org.jenkinsci.remoting.engine.WorkDirManager setupLogging
INFO: Both error and output logs will be printed to D:\Jenkins\remoting
Aug 04, 2024 5:14:14 PM hudson.remoting.Launcher createEngine
Заранее спасибо.
1. Да 2. Я всегда могу вернуться к C# в Powershell 3. Пока работаю над самим EXE, служба будет использована позже.
В качестве отступления: вызов jave.exe через cmd /C здесь не обязателен, но в отношении завершения процесса PowerShell, выполняющего скрипт, не должно быть никакой разницы. Напротив, процесс, запущенный aStart-Process, — это независимый процесс (а не дочерний процесс вызывающего объекта), который по умолчанию запускается асинхронно и в новом окне. Только в необычных ситуациях требуется Start-Process; прямой вызов (через & или просто по имени/пути, если оно не заключено в кавычки и не содержит переменных) почти всегда является лучшим решением.





Напишите один или несколько сценариев, способных получить pid (идентификатор процесса) запущенного процесса или каким-либо образом запросить операционную систему, чтобы найти уникальный процесс (в вашем случае jenkins). Затем используйте pid, чтобы завершить процесс.
Если вам удастся запустить процесс в фоновом режиме, его будет легко остановить позже с помощью службы Windows или аналогичной даже на другой ОС (Mac, Linux).
Предлагаю вам почитать на эту тему. По сути, фоновый процесс — это когда вы запускается оболочкой, но оболочка не блокируется. Процесс переднего плана — это когда оболочка остается заблокированной после ее запуска. В этом случае вам нужно нажать Ctrl+C, чтобы выйти из приложения, и оболочка снова станет доступной для использования.
Более подробная информация здесь. Также он работает на окнах.
Независимо от операционной системы (Windows, Linux, Mac), если вам удастся создать эти сценарии, процесс будет легко запускаться и останавливаться.
В Linux мы можем получить pid недавно запущенного процесса. Используя этот pid, я могу закрыть приложение из другой оболочки или сценария. У меня нет Windows, но в основном алгоритм такой:
start.bat
стоп.бат
Несколько лет назад я использовал этот инструмент http://nssm.cc/download для создания службы Windows из файла java. Это было легко. Остановка сработала как положено (процесс Java завершился)
Если я не ошибаюсь, фоновый процесс не требовался. Я просто установил расположение bat-скриптов (start.bat/stop.bat). Запуск/остановка использования службы Windows сработала как положено.
Я писал подобные скрипты для Windows и Linux. Использование bat или powershell доставляет неудобства. Как будто они были созданы не для автоматизации задач. Простые строковые алгоритмы настолько сумасшедшие, что их трудно понять
В Linux очень легко создавать подобные скрипты.
С докером это было бы легко. Даже служба Windows не потребуется, поскольку вы можете настроить запуск контейнера при запуске компьютера. В любом случае с докером вам нужно только:
Эти команды можно зарегистрировать в вашей службе Windows, и они будут работать без ошибок.
Ваша проблема заключается в неожиданном отображении строк stderr, которые отображаются неправильно, как если бы они были ошибками. Чтобы избежать проблемы, выполните следующие действия:
Примените перенаправление2>&1 непосредственно к вызову java.exe.
java.exe объединяется с потоком вывода PowerShell (аналог stdout PowerShell), что позволяет обрабатывать как вывод stdout, так и вывод stderr в конвейере PowerShell.Передайте результат вызову ForEach-Object, который вызывает метод .ToString() для каждого результирующего объекта (% — это встроенный псевдоним ForEach-Object).
.ToString() дает исходный текст stderr.[1]Примените к последнему перенаправление в файл журнала (>>"$JenkinsPath\agent.log"); поскольку весь вывод java.exe в этот момент маршрутизируется через поток вывода успеха >>, достаточно (т. е. нет необходимости в *>> для захвата всех потоков).
# java.exe arguments omitted for brevity
& "$Java\java.exe" ... 2>&1 | % ToString >>"$JenkinsPath\agent.log"
Более простая альтернатива через Добавить контент:
# java.exe arguments omitted for brevity
& "$Java\java.exe" ... 2>&1 | Add-Content "$JenkinsPath\agent.log"
Add-Content, как и Set-Content, неявно преобразует в строку свои входные объекты через .ToString().
Предостережение относительно кодировки символов:
В PowerShell (Core) 7 оба решения эквивалентны и создают файлы UTF-8 без спецификации, учитывая, что эта кодировка является согласованной по умолчанию в этой версии PowerShell.
Напротив, в Windows PowerShell (устаревшая версия, поставляемая вместе с Windows, последняя и последняя версия которой — 5.1.x) операторы перенаправления > / >> фактически являются псевдонимами Out-File, который по умолчанию имеет значение UTF- 16LE со спецификацией («Юникод»), тогда как Add-Content/Set-Content по умолчанию используют активную устаревшую кодовую страницу ANSI системы; при необходимости используйте параметр -Encoding, но учтите, что -Encoding utf8 всегда создает файл UTF-8 со спецификацией.
[2]
[1] Specifically, it is the first stderr line output by an external program such as java.exe that is rendered this way when a 2> or *> redirection (or a >> variant) is applied to an external-program call. In the console (terminal), subsequent stderr lines render by their text only, but are printed in red too. When redirecting such output to a file, such as in your case, coloring is lost, so it is only the first, error-like representation that stands out. A simple test command:cmd /c 'echo stderr1 >&2 & echo stdout1 & echo stderr2 >&2' 2>&1
Note that the original output order among the stdout and stderr streams isn't always maintained - see GitHub issue #5424 for a discussion.
Спасибо. Работало как шарм.
Рад это слышать, @EliorMachlev.
#1 Если вы работаете с открытым исходным кодом, обязательна ли Windows? №2 обязателен ли powershell? Как вы создаете службу Windows?