Войти

Показать полную графическую версию : bat-скрипт, удаление строк, настоящий рандом


FeranD
26-06-2017, 02:16
Друзья, очень прошу вашей помощи в написании скрипта.
Задача такая. В папке, где будет лежать скрипт, находится 2 файла
1.config.txt
2. config.txt.bak
Файлы текстовые, содержать конфиг для работы майнера(xmr-stak-cpu), но это не суть важно. В фоне будет запущен процесс с именем xmr.exe.

Скрипт должен работать в фоновом режиме на постоянку, планирую запустить его службой.
Коротко, алгоритм работы скрипта таковой:

Пока (true) выполнять:
1. Удалить из файла config.txt случайное количество строк(от 1-5) начиная со строки №
2. Убить процесс xmr.exe
3. Подождать случайное количество времени(от 5 до 15 минут)
4. Скопировать файл config.txt.bak на место файла config.txt
5. Убить процесс xmr.exe (таким образом перезапускается майнер и подхватывает новый конфиг, майнер работает службой)
6. Подождать случайное количество времени(от 20 до 40 минут)
Конец ПОКА

Проблемы с которыми я столкнулся, это в первую очередь генерация случайного числа через переменную %random%, число псевдо случайное и зависит от какой-то постоянной величины из внутренней среды виндовс. Так как скрипт будет работать на 20+ машинах одновременно нужна случайность на каждой отдельной машине. Дальше, я совсем не представляю каким образом можно удалить строки из файла config.txt. Номер строки заранее известен.

Iska
26-06-2017, 02:52
«Настоящий рандом» Вы можете получить исключительно внешним фактором — например, подбрасывая монетку и записывая результат. Для машины это всегда будет ряд псевдослучайных чисел. В любом случае, Вам стоит подумать о WSH/PowerShell — пакетные файлы слабо подходят на указанную роль.

megaloman
02-07-2017, 22:08
FeranD, File1 = "config.txt"
File2 = "config.txt.bak"
ProcName = "xmr.exe"

Wait1_1 = 5 ' время в мин.
Wait1_2 = 15
Wait2_1 = 20
Wait2_2 = 40

NBegin = 10 ' Начиная со строки
NDel1 = 1 ' Удалить случайное число строк в диапазоне
NDel2 = 5

Set FSO = CreateObject("Scripting.FileSystemObject")

Randomize

ScrName = WScript.ScriptFullName
ScrPath = FSO.GetParentFolderName(ScrName)
If Right(ScrPath, 1) <> "\" Then ScrPath = ScrPath + "\"

Do
On Error Resume Next
Set NFile = FSO.OpenTextFile(ScrPath + File2, 1, False) ' Открываем текстовый файл

If Err.Number <> 0 Then
MsgBox ScrPath + File2 + vbCrLf + vbCrLf + Err.Description
Exit Do
End If

S = NFile.ReadAll
NFile.Close
On Error GoTo 0

Mas = Split(S, vbCrLf)
NU = UBound(Mas)
NL = LBound(Mas)

NDel = Int((NDel2 - NDel1 + 1) * Rnd() + NDel1)

On Error Resume Next
Set NFile = FSO.OpenTextFile(ScrPath + File1, 2, True) ' Открываем текстовый файл

If Err.Number <> 0 Then
MsgBox ScrPath + File1 + vbCrLf + vbCrLf + Err.Description
Exit Do
End If

j = 0
For i = NL To NU
If i >= NBegin + NL - 1 And j < NDel Then
j = j + 1
Else
NFile.WriteLine (Mas(i))
End If
Next
NFile.Close
On Error GoTo 0
If TermWait(ProcName, Rnd(), Wait1_1, Wait1_2) <> -1 Then Exit Do

On Error Resume Next
LL = FSO.CopyFile(ScrPath + File2, ScrPath + File1, True)

If Err.Number <> 0 Then
MsgBox Err.Description
Exit Do
End If
On Error GoTo 0
If TermWait(ProcName, Rnd(), Wait2_1, Wait2_2) <> -1 Then Exit Do
Loop

Function TermWait(Proc, TRnd, W1, W2)
LL = -1
Set WMI = GetObject("winMgmts:")
SQuery = "Select *From Win32_Process Where Name=" + """" + Proc + """"

Set Processes = WMI.ExecQuery(SQuery)
If Processes.Count <> 0 Then
On Error Resume Next
For Each Process In Processes
Process.Terminate
Next
On Error GoTo 0
End If

TWait = Int(((W2 - W1) * 60 + 1) * TRnd + W1 * 60)

' Set WShell = CreateObject("WScript.Shell")
' LL = WShell.Popup("Ждем " + CStr(Int(TWait)) + " сек" + vbCrLf + vbCrLf + """OK"" - завершить скрипт", TWait, CStr(Time()), 48)

WScript.Sleep (TWait * 1000)

TermWait = LL
End Function




© OSzone.net 2001-2012