Я пытаюсь запустить программу в блоке сценариев Start-job, используя переменную для пути. Вот строка:
$using:plinkdir\plink.exe -telnet $using:ip -P $using:port | TimeStamp >> "$using:LogDir\WeightLog_$(get-date -f MM-dd-yyyy).txt"
Все переменные работают, вся строка работает, когда я использую c:\plink вместо переменной $plink. Он выдает ошибку в -telnet, поэтому не получает аргументы для plink.
Вот $var и работа:
$LogDir = "c:\users\user" # Log file output directory
$PlinkDir = "C:" # plink.exe directory
$SerialIP = "1.1.1.1" # serial device IP address
$SerialPort = 10000 # port to log
function CaptureWeight {
Start-Job -Name WeightLog -ScriptBlock {
# Bring Variables into job from callers scope
#$LogDir = $using:LogDir
#$PlinkDir = $using:PlinkDir
#$SerialIP = $using:SerialIP
#$SerialPort = $using:SerialPort
# Set TimeStamp format
filter timestamp {"$(Get-Date -Format MM/dd/yyyy_HH:mm:ss) $_"}
# Start plink, pipe output to TimeStamp, redirect to log file
$using:PlinkDir\plink.exe -telnet $using:SerialIP -P $using:SerialPort | TimeStamp >> "$using:LogDir\WeightLog_$(get-date -f MM-dd-yyyy).txt"
}
}
Спасибо!
Сообщение @SantiagoSquarzon обновлено, спасибо.
Попробуйте вместо этого & "$using:PlinkDir\plink.exe" -telnet...
(обратите внимание на двойные кавычки)
Это сработало более или менее после того, как я изменил значение $PlinkDir на «c:\users\user», но добавил пробел между каждым символом и пустую строку между каждой строкой в выводе в файл журнала, интересный результат.
Замените TimeStamp >> ..
на TimeStamp | Set-Content -Encoding utf8 "$using:LogDi....
ПРИМЕЧАНИЕ. Это заменит существующий файл, если он существует. Если вы хотите добавить к существующему файлу, используйте вместо этого Add-Content
Это помогло решить исходную проблему и проблему с дополнительным интервалом. Это возвращает меня к тому, почему я использовал перенаправление, оно оставляет файл незаблокированным для просмотра. Он не потерял никаких данных, когда powershell неожиданно отключился. Я добираюсь до ОКР, думаю, эта переменная используется только один раз. В настоящее время я думаю, что мой лучший вариант - не использовать переменную для пути к программе. Хотя это так близко к тому, что я хотел. Обновлено: приведенное выше, вероятно, должно быть ответом на этот вопрос, если у вас нет другой идеи для перенаправления.
>>
это псевдоним для Out-File -Append
, немного отличающийся от Set-Content
Две другие вещи крутились у меня в голове, используя Invoke-command, я нашел некоторую информацию об этом и предпочел бы, чтобы это было проще. Другое дело, добавьте plink в среду (путь/переменная?) только для сеанса, чтобы его можно было запустить, например, в блокноте или иначе без пути. Моя формулировка поиска по этому вопросу могла быть ошибочной, поскольку я не мог найти то, что искал.
Итак, я понимаю, что вам нужно запустить это в задании, потому что вы хотите убить его в определенное время, пока занимаетесь другими делами, и вы ожидаете, что данные, выводимые plink.exe
до того момента, когда задание было уничтожено, будут записаны в файл. Это правильное предположение? И если да, то как вы убиваете работу (используете ли вы Stop-Job
)?
Правильно, я упомяну, что «другие вещи» - это просто расчет времени, чем команда ожидания, затем команда остановки, чтобы журнал можно было проанализировать, и он мог начаться снова с новым именем файла даты. Я хочу, чтобы он запустился, ПК загружался и работал до тех пор, пока он работает, может быть месяц или больше. Хотите сделать это только с одной запланированной задачей при загрузке. Я могу сделать все это в настоящее время за вычетом одной переменной для пути к программе. Обновлено: да, просто остановите его с помощью stop-job в сценарии, а затем запустите его снова.
Этот ответ основан на некоторых предположениях и догадках о том, что может сработать для того, что объяснено в вашем вопросе и комментариях.
Прежде всего, чтобы объяснить «Он не потерял никаких данных, когда PowerShell был неожиданно закрыт»., это потому, что >>
(псевдоним для Out-File -Append
):
Итак, когда вы убиваете задание, то, что есть, все еще там в основном. Я рекомендовал вам использовать Set-Content
, но это было до того, как я понял, что вы делаете, в этом случае это был бы не вариант.
Альтернативой, предлагаемой здесь, является использование StreamWriter
, что хорошо, потому что мы можем держать файловый поток открытым и добавлять в файл по мере необходимости без необходимости каждый раз закрывать поток (это также позаботится о "пустая строка между каждой строкой в выводе в файл журнала"). Чтобы обойти убивая задание, но сохраняя результаты в файл, мы можем использовать try / finally
заявление.
$LogDir = "c:\users\user" # Log file output directory
$PlinkDir = "C:" # plink.exe directory
$SerialIP = "1.1.1.1" # serial device IP address
$SerialPort = 10000 # port to log
function CaptureWeight {
Start-Job -Name WeightLog -ScriptBlock {
filter timestamp {
$sw.WriteLine("$(Get-Date -Format MM/dd/yyyy_HH:mm:ss) $_")
}
try {
$sw = [System.IO.StreamWriter]::new("$using:LogDir\WeightLog_$(Get-Date -f MM-dd-yyyy).txt")
& "$using:PlinkDir\plink.exe" -telnet $using:SerialIP -P $using:SerialPort | TimeStamp
}
finally {
$sw.ForEach('Flush')
$sw.ForEach('Dispose')
}
}
}
$job = CaptureWeight # For testing, save the job
Start-Sleep -Seconds 60 # wait 1 minute
$job | Stop-Job # kill the job
Get-Content "$LogDir\WeightLog_$(Get-Date -f MM-dd-yyyy).txt" # Did it work?
Это работает отлично, позволяет использовать переменную для пути к программе, не теряет данные при неожиданном закрытии/сбое, выглядит лучше. Как наблюдение, при попытке просмотреть файл во время его работы кажется, что он обновляется (для просмотра) примерно каждые 2 минуты, вы получаете один 2-минутный фрагмент данных, который отстает примерно на 2 минуты, 2-минутные данные есть . Функционально это совершенно нормально.
@Retrotube с удовольствием! Я рад, что это сработало, в основном это было основано на догадках, хе-хе. Рег. "обновление файла" через 2 минуты. Вы можете установить свойство .AutoFlush
для $sw
на $true
, которое должно заботиться об обновлении файла при каждом вызове .WriteLine
. Меня сейчас нет дома, трудно редактировать код с телефона. Вы можете задать новый вопрос, и если никто не ответит, я отвечу, когда вернусь.
Спасибо за вашу помощь! собирается запустить это в производство в ближайшее время, чтобы контролировать серийные весы. Это нормально, данные есть, и для целей просмотра 2-минутная задержка в порядке. Я могу поиграть с этой частью больше, если это необходимо.
Все еще играл с этим, пытаясь найти лучший способ очистки журналов. Интересно, можно ли игнорировать некоторые строки и не записывать их с самого начала. Похоже, что оператор If может, но не уверен, где его попробовать. Начал новый вопрос здесь: stackoverflow.com/questions/72177600
Поделитесь всем кодом (определением переменных, а также оператором
start-job
)